欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CAS之5.2x版本之客户端集成(Springboot)-yellowcong

程序员文章站 2022-05-05 12:10:15
...

Springboot和cas集成开发,主要也就是配置了四个过滤器,和一个监听器到Springboot中,其实和传统的配置方式,没有太大的区别。只是将web.xml配置都通过代码的配置放到了springboot的启动类中。

项目地址

https://gitee.com/yellowcong/springboot_cas/tree/master/cas-client-springboot

目录结构

CAS之5.2x版本之客户端集成(Springboot)-yellowcong

三个系统
CAS之5.2x版本之客户端集成(Springboot)-yellowcong

架构

节点 功能 目录
https://yellowcong.com:9000 cas服务端 cas-server-login
https://yellowcong.com:8888 cas客户端 cas-client-springboot
https://yellowcong.com:8889 cas客户端 cas-client-springboot2

1、创建过滤器类

用于过滤不需要登录的用户,需要实现UrlPatternMatcherStrategy 接口,在matches 添加不需要用户登录的类

package com.yellowcong.cas.auth;

import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy;

/**
 * 创建日期:2018年2月3日<br/>
 * 创建时间:下午5:36:48<br/>
 * 创建者    :yellowcong<br/>
 * 机能概要:过滤掉一些不需要授权,登录的界面
 */
public class SimpleUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy {

    /**
     * 创建日期:2018年2月3日<br/>
     * 创建时间:下午5:42:36<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要: 判断是否匹配这个字符串
     * @param url 用户请求的连接
     * @return true : 我就不拦截你了
     *         false :必须得登录了
     */
    @Override
    public boolean matches(String url) {
        //http://yellowcong.com:8080/cas-client-maven/user/loginOut/success
        //当含有loginout的字段,就可以不用登录了
        return url.contains("/loginOut/success");
    }

    /**
     * 正则表达式的规则,这个地方可以是web传递过来的
     */
    @Override
    public void setPattern(String pattern) {

    }
}

2、创建首页和用户登出控制器

首页控制器

package com.yellowcong.cas.controller;

import java.security.Principal;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {

    @RequestMapping("/index")
    public String index(HttpServletRequest request) {

        //获取cas给我们传递回来的对象,这个东西放到了session中
        //session的 key是 _const_cas_assertion_
        Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);  

        //获取登录用户名
        String loginName =assertion.getPrincipal().getName();
        System.out.printf("登录用户名:%s\r\n",loginName);

        //获取自定义返回值的数据
        Principal principal  = (AttributePrincipal) request.getUserPrincipal();
        if (request.getUserPrincipal() != null) {

            if (principal instanceof AttributePrincipal) {
                //cas传递过来的数据
                Map<String,Object> result =( (AttributePrincipal)principal).getAttributes();
                for(Map.Entry<String, Object> entry :result.entrySet()) {
                    String key = entry.getKey();
                    Object val = entry.getValue();
                    System.out.printf("%s:%s\r\n",key,val);
                }
            }
        }

        return "index";
    }
}

首页代码(index.jsp)

<%@ page import="org.jasig.cas.client.authentication.AttributePrincipal" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>index</title>
</head>
<body>
<h1>当前所在子系统:测试系统1</h1>
<h2><a href="http://yellowcong.com:8888/">系统1</a></h2>
<h2><a href="http://yellowcong.com:8889/">系统2</a></h2>
<b>Authenticated User Id:</b> <a href="logout.jsp" title="Click here to log out"><%= request.getRemoteUser() %>
</a>
<br/>
<a href="<%=request.getContextPath() %>/user/loginOut1" title="Click here to log out">退出系统(方式1)</a>
<a href="<%=request.getContextPath() %>/user/loginOut2" title="Click here to log out">退出系统(方式2)</a>
<%
    if (request.getUserPrincipal() != null) {
        AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();

        final Map attributes = principal.getAttributes();

        if (attributes != null) {
            Iterator attributeNames = attributes.keySet().iterator();
            out.println("<b>Attributes:</b>");

            if (attributeNames.hasNext()) {
                out.println("<hr><table border='3pt' width='100%'>");
                out.println("<th colspan='2'>Attributes</th>");
                out.println("<tr><td><b>Key</b></td><td><b>Value</b></td></tr>");

                for (; attributeNames.hasNext(); ) {
                    out.println("<tr><td>");
                    String attributeName = (String) attributeNames.next();
                    out.println(attributeName);
                    out.println("</td><td>");
                    final Object attributeValue = attributes.get(attributeName);

                    if (attributeValue instanceof List) {
                        final List values = (List) attributeValue;
                        out.println("<strong>Multi-valued attribute: " + values.size() + "</strong>");
                        out.println("<ul>");
                        for (Object value : values) {
                            out.println("<li>" + value + "</li>");
                        }
                        out.println("</ul>");
                    } else {
                        out.println(attributeValue);
                    }
                    out.println("</td></tr>");
                }
                out.println("</table>");
            } else {
                out.print("No attributes are supplied by the CAS server.</p>");
            }
        } else {
            out.println("<pre>The attribute map is empty. Review your CAS filter configurations.</pre>");
        }
    } else {
        out.println("<pre>The user principal is empty from the request object. Review the wrapper filter configuration.</pre>");
    }
%>
</body>
</html>

用户登出控制器

登出的方式,有两种,一种是直接退出后,到默认试图,第二种是自己配置推出后,需要访问额url

package com.yellowcong.cas.controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/user")
public class LoginController {
    /**
     * 创建日期:2018年2月3日<br/>
     * 创建时间:下午5:32:41<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:单点登出
     * 
     * @param session
     * @return
     */
    @RequestMapping("/loginOut1")
    public String loginOut(HttpSession session) {
        session.invalidate();
        // http://yellowcong.com:8080/cas-client-maven/user/loginOut/success

        // 这个是直接退出,走的是默认退出方式
        return "redirect:https://yellowcong.com:9000/logout";
    }

    @RequestMapping("/loginOut2")
    public String loginOut2(HttpSession session) {
        session.invalidate();
        // 退出登录后,跳转到退成成功的页面,不走默认页面
        return "redirect:https://yellowcong.com:9000/logout?service=http://yellowcong.com:8888/user/loginOut/success";
    }

    @RequestMapping("/loginOut/success")
    @ResponseBody
    public String loginOut2() {
        return "注销成功";
    }

}

3、配置过滤器到springboot

package com.yellowcong.cas;

import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;

import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SpringBootApplication
public class ConfigMain {
    //url的前缀
    private static final String CAS_SERVER_URL_PREFIX = "https://yellowcong.com:9000";

    //本机的名称
    private static final String SERVER_NAME = "http://yellowcong.com:8888";

    /**
     * 登录过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterSingleRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new SingleSignOutFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        Map<String,String>  initParameters = new HashMap<String, String>();
        initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
        registration.setInitParameters(initParameters);
        // 设定加载的顺序
        registration.setOrder(1);
        return registration;
    }

    /**
     * 过滤验证器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterValidationRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        Map<String,String>  initParameters = new HashMap<String, String>();
        initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX);
        initParameters.put("serverName", SERVER_NAME);
        initParameters.put("useSession", "true");
        registration.setInitParameters(initParameters);
        // 设定加载的顺序
        registration.setOrder(1);
        return registration;
    }

    /**
     * 授权过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterAuthenticationRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AuthenticationFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        Map<String,String>  initParameters = new HashMap<String, String>();
        initParameters.put("casServerLoginUrl", CAS_SERVER_URL_PREFIX);
        initParameters.put("serverName", SERVER_NAME);
        initParameters.put("ignorePattern", ".*");
        //表示过滤所有
        initParameters.put("ignoreUrlPatternType", "com.yellowcong.cas.auth.SimpleUrlPatternMatcherStrategy");

        registration.setInitParameters(initParameters);
        // 设定加载的顺序
        registration.setOrder(1);
        return registration;
    }

    /**
     * wraper过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterWrapperRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new HttpServletRequestWrapperFilter());
        // 设定匹配的路径
        registration.addUrlPatterns("/*");
        // 设定加载的顺序
        registration.setOrder(1);
        return registration;
    }

    /**
     * 添加监听器
     * @return
     */
    @Bean  
    public ServletListenerRegistrationBean<EventListener> singleSignOutListenerRegistration(){  
        ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<EventListener>();  
        registrationBean.setListener(new SingleSignOutHttpSessionListener());  
        registrationBean.setOrder(1);  
        return registrationBean;  
    }  

    /**
     * @author yellowcong
     * 创建日期:2018/02/05
     * 设定首页
     */
    @Configuration
    public class DefaultView extends WebMvcConfigurerAdapter {

        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            //设定首页为index
            registry.addViewController("/").setViewName("forward:/index");

            //设定匹配的优先级
            registry.setOrder(Ordered.HIGHEST_PRECEDENCE);

            //添加视图控制类
            super.addViewControllers(registry);
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(ConfigMain.class, args);
    }
}

4、配置application.yml

需要设定springboot的默认端口号,项目名称的信息

logging:
  #日志存储地址
  file: "logs/config/demo-xx.log"
info:
  name : "入门案例"

server:
  #端口号
  #http://yellowcong.com:8888/
  port: 8888
  #项目名,如果不设定,默认是 /
  context-path: /

spring:
  mvc:
    view:
      # 页面默认前缀目录
      prefix: /WEB-INF/jsp/
      # 响应页面默认后缀
      suffix: .jsp

5、配置pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>yellowcong.com</groupId>
  <artifactId>cas-client-springboot</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>cas-client-springboot</name>
  <url>http://maven.apache.org</url>

   <!-- 引用父类依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.cas.client.version>3.5.0</java.cas.client.version>
    </properties>

    <dependencies>
        <!-- 添加spring-web的依赖,直接就可以使用springmvc了 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--cas的客户端 -->
        <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-core</artifactId>
            <version>${java.cas.client.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!-- 添加spring的插件, 就可以直接通过 mvn spring-boot:run 运行了 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

登录测试

我们先登录8888端口的系统,然后再跳转到8889端口的系统,最后退出系统,走的是自定义返回的界面。
CAS之5.2x版本之客户端集成(Springboot)-yellowcong