【SpringBoot】SpringBoot+SpringSecurity+CAS实现单点登录

news2024/11/28 16:37:12

文章目录

  • 一.CAS的概述
    • 1.SSO
    • 2.CAS
    • 3.概念
  • 二.CAS的流程
  • 三.CAS服务端部署
    • 1.下载地址
    • 2.源码打包
    • 3.部署运行
    • 4. java.io.FileNotFoundException: \etc\cas\thekeystore (系统找不到指定的文件。)
  • 四.CAS的定制
    • 1.定制数据源
    • 2.兼容 HTTP
    • 3.定制登录页
  • 五.SpringBoot集成CAS
    • 1.工程创建
    • 2.导入依赖
    • 3.修改包名
    • 4.编写配置文件
    • 5.编写角色授权
    • 6.编写配置对象
    • 7.编写控制器类
    • 8.启动项目测试
  • 六. SpringBoot-jar的方式启动 cas-server
  • 七.cas.properties配置项介绍

一.CAS的概述

1.SSO

在这里插入图片描述

2.CAS

CAS(Central Authentication Service的缩写,中央认证服务) 是耶鲁大学 Technology and Planning 实验室的 Shawn Bayern 在2002年出的一个开源系统。刚开始名字叫Yale CAS。Yale CAS 1.0的目标只是一个单点登录的系统,随着慢慢公开,功能就越来越多了,2.0就提供了多种认证的方式。

  • 从结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。只要将开发单点登录的系统集成CAS Client,然后部署好CAS Server ,就可以实现多系统的单点登录。

  • 官网地址:https://www.apereo.org/projects/cas

  • 源码地址:https://github.com/apereo/cas-overlay-template/tree/5.3

特点:

  • 开源的企业级单点登录解决方案。
  • CAS Server 为需要独立部署的 Web 应用。
  • CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包 括 Java, .Net, PHP, Perl,Apache, uPortal, Ruby 等。

3.概念

  • CAS Server(CAS服务端)需要独立部署,负责完成对用户的认证工作,完成与浏览器端的用户认证和CAS客户端的票据验证。

  • CAS Client(CAS客户端)负责处理对受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。 CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。

  • TGT( Ticket Granting Ticket):相当于我们平时所见到的 HttpSession 的作用,用户登录成功后,用户的基本信息,如用户名、登录有效期等信息,都将存储在此。

    • TGT 是 CAS 为用户签发的登录票据,拥有了 TGT,用户就可以证明自己在CAS成功登录过。 TGT 封装了 Cookie 值以及此 Cookie 值对应的用户信息。用户在 CAS 认证成功后,CAS 生成 cookie(叫TGC),写入浏览器,同时生成一个 TGT 对象,放入自己的缓存,TGT 对象的 ID 就是 cookie 的值。 当 HTTP 再次请求到来时,如果传过来的有 CAS 生成的 cookie,则 CAS 以此 cookie 值为 key 查询缓存中有无 TGT,如果有,说明用户之前登录过,如果没有,则用户需要重新登录。
  • TGC(Ticket Granting Cookie):存放用户身份认证凭证的 cookie,在浏览器和 CAS Server 间通讯时使用,并且只能基于安全通道传输(Https),是 CAS Server 用来明确用户身份的凭证。根据 TGC 可以帮助用户找到对应的 TGT,所以这个 TGC 有点类似与会话 ID

  • ST( Service Ticket):服务票据,服务的惟一标识码 , 由 CAS Server 发出( Http 传送),用户访问 Service 时,Service 发现用户没有 ST,则要求用户去 CAS 获取 ST。

    • 这是 CAS Sever 通过 TGT 给用户发放的一张票据,用户在访问其他服务时,发现没有 Cookie 或者 ST ,那么就会302CAS Server 获取 ST,然后会携带着 ST 302 回来,CAS Client 则通过 ST 去 CAS Server 上获取用户的登录状态。

SERVICE TICKET(ST)

二.CAS的流程

下图是 CAS 最基本的协议过程,主要有以下步骤:

  1. 用户webBrowser访问cas-client,被拦截重定向到cas-server进行登录,输入正确的用户信息

  2. 登录成功后,cas-server签发一个TGC票据,写入浏览器同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是cookie的值,同时携带着ST票据,再次跳转到cas-client, cas-client发现有ST票据则拿着ST票据去cas-server验证ST票据,如果验证通过,则返回用户名信息

  3. cas-client登录成功,用户访问另一个cas-client2时,也会被拦截再次跳转到cas-server发现TGC票据生成的TGT对象的ID值存在则直接验证通过,签发一个ST票据给cas-client2。

在这里插入图片描述

  • CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址)以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到Service和新产生的 Ticket 过后,在第5,6 步中与 CAS Server 进行身份核实,以确保 Service Ticket 的合法性。

三.CAS服务端部署

1.下载地址

环境要求

  • JDK 8+
  • CAS 5.3x
    • CAS4.x 的server是基于Spring的,模版引擎使用的是JSP。
    • CAS5.X 之后使用的是基于SpringBoot的,模版引擎使用Thymeleaf
  • tomcat 8+

下载地址

  1. cas server 客户端模板下载 ,https://github.com/apereo/cas-overlay-template

  2. 目前最新版是6.x,但是需要java11以上,我们还是使用java8,所以选择了5.3
    在这里插入图片描述

2.源码打包

maven打包命令

mvn clean package -Dmaven.test.skip=true

在这里插入图片描述
在这里插入图片描述
更换下载源

如果你想要下载速度快点,请更换下载源,找到pom.xml中的repositories,使用aliyun代理服务器下载依赖

<repository>
    <id>aliyunmaven</id>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>

在这里插入图片描述

3.部署运行

由于打完包后是一个war包,需要tomcat才能运行

  • 下载路径:https://mirrors.bfsu.edu.cn/apache/tomcat/tomcat-8/v8.5.83/bin/

将打包好的cas.war,放到tomcat的webapps目录中,然后点击bin目录下的startup.bat启动。

正常启动后,在浏览器中输入地址:http://localhost:8080/cas/login,将会看到如下界面:

  • 默认用户名:casuser
  • 默认密码:Mellon

在这里插入图片描述
在这里插入图片描述

  • 使用上边提供的登出链接,还可以手动在地址栏输入http://localhost:8080/cas/logout
    在这里插入图片描述

4. java.io.FileNotFoundException: \etc\cas\thekeystore (系统找不到指定的文件。)

\etc\cas\thekeystore是生成的密钥文件的,由于我这里不使用加密,所以需要将cas的https协议忽略并将http协议设置为允许,步骤:

  1. 修改cas/WEB-INF/classes/application.properties,加入配置:
cas.tgc.secure=false
cas.serviceRegistry.initFromJson=true

在这里插入图片描述

  1. 修改services\HTTPSandIMAPS-10000001.json
    在这里插入图片描述

四.CAS的定制

1.定制数据源

1.如果要让cas直接连接数据库做用户认证,引入依赖

  • 找到源码目录cas-overlay-template-5.3中的pom.xml

    <!--数据库认证相关 start-->
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-jdbc</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apereo.cas</groupId>
        <artifactId>cas-server-support-jdbc-drivers</artifactId>
        <version>${cas.version}</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    <!--数据库认证相关 end-->
    

在这里插入图片描述
2 重新打包部署后重启tomccat

  • 找到源码目录cas-overlay-template-5.3,在地址栏输入cmd,然后回车,运行打包命令:mvn clean package -Dmaven.test.skip=true

3.加入数据源的配置

  • 打开apache-tomcat-8.5.61\webapps\cas\WEB-INF\classes目录,修改application.properties,注释cas.authn.accept.users=....禁用默认用户,添加数据库配置:
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/security_test2
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=root
cas.authn.jdbc.query[0].sql=select password from sys_user where username=?
cas.authn.jdbc.query[0].fieldPassword=password

在这里插入图片描述

4.数据库密码字段如果是加密的,需要cas配置密码加密规则

  • cas5.X 提供了4种加密配置:

    cas.authn.jdbc.query[0].passwordEncoder.type=NONE|DEFAULT|STANDARD|BCRYPT
    
  • 默认值为 NONE,这四种方式脱胎于spring security中的加密方式,spring security提供了 MD5PasswordEncoder、SHAPasswordEncoder、StandardPasswordEncoder和 BCryptPasswordEncoder。

  • NONE:对密码不做任何加密,即保留明文。
  • DEFAULT:启用DefaultPasswordEncoder。 MD5PasswordEncoder和 SHAPasswordEncoder加密是编码算法加密,现在cas把他们归属于 DefaultPasswordEncoder。DefaultPasswordEncoder需要带参数 encodingAlgorithm:cas.authn.accept.passwordEncoder.encodingAlgorithm=MD5|SHA
  • STANDARD:启用StandardPasswordEncoder加密方式 。1024次迭代的 SHA‐256 散列 哈希加密实现,并使用一个随机8字节的salt盐
  • BCRYPT:启用BCryptPasswordEncoder加密方式。

这里采用BCRYPT加密,因为我们数据库中的密码加密方式就是这种加密,应该保持一致,修改application.properties 配置文件。

cas.authn.jdbc.query[0].passwordEncoder.type=BCRYPT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8

5.导入数据库数据表

DROP DATABASE IF EXISTS `security_test2`;

CREATE DATABASE `security_test2`;

USE `security_test2`;

DROP TABLE IF EXISTS `sys_role`;

CREATE TABLE `sys_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色编号',
  `name` varchar(32) NOT NULL COMMENT '角色名称',
  `desc` varchar(32) NOT NULL COMMENT '角色描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

insert  into `sys_role`(`id`,`name`,`desc`) values (1,'ROLE_USER','用户权限');
insert  into `sys_role`(`id`,`name`,`desc`) values (2,'ROLE_ADMIN','管理权限');
insert  into `sys_role`(`id`,`name`,`desc`) values (3,'ROLE_PRODUCT','产品权限');
insert  into `sys_role`(`id`,`name`,`desc`) values (4,'ROLE_ORDER','订单权限');

DROP TABLE IF EXISTS `sys_user`;

CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `password` varchar(128) NOT NULL COMMENT '用户密码',
  `status` int(1) NOT NULL DEFAULT '1' COMMENT '用户状态(0:关闭、1:开启)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

insert  into `sys_user`(`id`,`username`,`password`,`status`) values (1,'zhangsan','$2a$10$M7fmKpMZEkkzrTBiKie.EeAKZhQDrWAltpCA1y/py5AU/8lyiNB8y',0);
insert  into `sys_user`(`id`,`username`,`password`,`status`) values (2,'lisi','$2a$10$M7fmKpMZEkkzrTBiKie.EeAKZhQDrWAltpCA1y/py5AU/8lyiNB8y',0);
insert  into `sys_user`(`id`,`username`,`password`,`status`) values (3,'wangwu','$2a$10$M7fmKpMZEkkzrTBiKie.EeAKZhQDrWAltpCA1y/py5AU/8lyiNB8y',0);

DROP TABLE IF EXISTS `sys_user_role`;

CREATE TABLE `sys_user_role` (
  `uid` int(11) NOT NULL COMMENT '用户编号',
  `rid` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY (`uid`,`rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `sys_user_role`(`uid`,`rid`) values (1,1);
insert  into `sys_user_role`(`uid`,`rid`) values (1,3);
insert  into `sys_user_role`(`uid`,`rid`) values (2,1);
insert  into `sys_user_role`(`uid`,`rid`) values (2,4);
insert  into `sys_user_role`(`uid`,`rid`) values (3,1);
insert  into `sys_user_role`(`uid`,`rid`) values (3,2);
insert  into `sys_user_role`(`uid`,`rid`) values (3,3);
insert  into `sys_user_role`(`uid`,`rid`) values (3,4);

2.兼容 HTTP

  1. CAS默认使用的是基于https协议( HTTP + SSL),需要改为兼容使用http协议,修改apache-tomcat-8.5.61\webapps\cas\WEB-INF\classes目录的application.properties文件

    • TGC:Ticket Granted Cookie (客户端用户持有,传送到服务器,用于验证)存放用户身份认证凭证的cookie,在浏览器和CAS Server间通讯时使用,并且只能基于安全通道传输(Https),是CAS Server用来明确用户身份的凭证。
    cas.tgc.secure=false
    cas.serviceRegistry.initFromJson=true
    
  2. 修改apache-tomcat-8.5.61\webapps\cas\WEB-INF\classes\services目录下的HTTPSandIMAPS-10000001.json修改内容如下,即添加http

    {
      "@class" : "org.apereo.cas.services.RegexRegisteredService",
      "serviceId" : "^(https|http|imaps)://.*",
      "name" : "HTTPS and IMAPS",
      "id" : 10000001,
      "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
      "evaluationOrder" : 10000
    }
    
  3. 重新启动tomcat,然后zhangsan登录进行测试,或许看起来并没有什么不一样,但是现在已经兼容http协议

3.定制登录页

CAS项目结构

  • 静态资源(js、css) 存放目录为WEB-INF\classes\static
  • html资源(thymeleaf模板) 存放目录为WEB-INF\classes\templates
  • 主题配置文件存放在WEB-INF\classes,并且命名为[theme_name].properties
  1. 在静态资源目录(WEB-INF\classes\static\themes)下创建一个文件夹,一般跟工程名字保持一致,这里我们叫mylogin然后把咱们的css和js都拷贝进去
    在这里插入图片描述

  2. 在模板资源目录(WEB-INF\classes\static\templates)创建一个文件夹,一般跟工程名字保持一致,这里我们叫mylogin,把咱们的静态资源 login.html 拷贝到这里,然后把名称改为 casLoginView.html
    在这里插入图片描述

  3. 登录页面模板添加thymeleaf的命名空间

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    
  4. 修改所有静态资源的路径,改成绝对路径

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>自定义登录页</title>
        <link rel="stylesheet" href="/cas/themes/mylogin/css/bootstrap.min.css">
    </head>
    <body>
    ...
    ...    
    <script src="/cas/themes/mylogin/js/jquery-3.5.1.min.js"></script>
    <script src="/cas/themes/mylogin/js/bootstrap.bundle.min.js"></script>
    </body>
    </html>
    
  5. 修改表单的提交路径并加上特定对象属性

    <form th:object="${credential}" action="login" method="post">
    ...
    ...    
    </form>
    
  6. 修改表单的用户名和密码文本框都添加上一个th:field属性,并去掉无用属性

    ...
    <input type="text" class="form-control" th:field="*{username}" placeholder="请输入用户" required>
    ...
    <input type="text" class="form-control" th:field="*{password}" placeholder="请输入密码" required>
    ...
    
  7. 为此表单添加登录失败错误信息以及隐藏域表单项,直接拷贝以下代码到button提交按钮上边即可

    <div class="form-group" th:if="${#fields.hasErrors('*')}">
        <span th:each="err : ${#fields.errors('*')}" th:utext="${err}"></span>
    </div>
    <input type="hidden" name="execution" th:value="${flowExecutionKey}"/>
    <input type="hidden" name="_eventId" value="submit"/>
    <input type="hidden" name="geolocation"/>
    
  8. apache-tomcat-8.5.61\webapps\cas\WEB-INF\classes目录下创建一个主题配置文件,名字叫mylogin.properties,配置内容如下:

    cas.standard.css.file=/css/cas.css
    
  9. 找到application.properties配置文件,在文件的最后,我们启用默认主题为我们自己的主题即可。

    cas.theme.defaultThemeName=mylogin
    
  10. 重启tomcat应用,访问登录地址:http://localhost:8080/cas/login,您将会看到如下界面:

    在这里插入图片描述

  11. 登录测试,使用账号zhangsan,密码:123456进行登录测试。好就这样,我们保持工程启动状态,接下来,进行下一环节。

在这里插入图片描述

五.SpringBoot集成CAS

1.工程创建

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.导入依赖

<!--跟数据库进行的整合-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>
<!--跟Spring Security+CAS进行的整合-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-cas</artifactId>
</dependency>

3.修改包名

com.oyjp.domain:用于存放实体对象
com.oyjp.prop:用于存放配置属性类
com.oyjp.mapper:用于存放映射文件
com.oyjp.service:用于存放服务接口
com.oyjp.controller:用于存放控制器类
com.oyjp.config:用于存放配置对象

4.编写配置文件

server:
  port: 9001
  servlet:
    application-display-name: cas-resource-order
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/security_test2
    username: root
    password: root
mybatis:
  type-aliases-package: com.oyjp.domain
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.oyjp: debug

#自定义配置:APP配置信息(资源端)
app:
  server:
    host:
      #APP服务地址(绝对路径)
      url: http://localhost:9001
      #APP登录地址(相对路径)
      login_url: /login
      #APP退出地址(相对路径)
      logout_url: /logout

#自定义配置:CAS配置信息(认证端)
cas:
  server:
    host:
      #CAS服务地址(绝对路径)
      url: http://localhost:8080/cas
      #CAS登录地址(绝对路径)
      login_url: ${cas.server.host.url}/login
      #CAS退出地址(绝对路径)
      logout_url: ${cas.server.host.url}/logout?service=${app.server.host.url}

5.编写角色授权

@Service
@Transactional
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired(required = false)
    private SysUserMapper sysUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return sysUserMapper.findByUsername(username);
    }
}

6.编写配置对象

/**
 * 自定义属性配置类
 */
@Component
@Data
public class CasProperties {
    /**
     * 自定义配置:CAS配置信息(认证端
     */
    //CAS服务地址(绝对路径)  http://localhost:8080/cas
    @Value("${cas.server.host.url}")
    private String casServerUrl;
    //CAS登录地址(绝对路径)   ${cas.server.host.url}/login
    @Value("${cas.server.host.login_url}")
    private String casServerLoginUrl;
    //CAS退出地址(绝对路径)   ${cas.server.host.url}/logout?service=${app.server.host.url}
    @Value("${cas.server.host.logout_url}")
    private String casServerLogoutUrl;


    /**
     * 自定义配置:APP配置信息(资源端)
     */
    //APP服务地址(绝对路径) http://localhost:9001
    @Value("${app.server.host.url}")
    private String appServerUrl;

    //APP登录地址(相对路径)  /login
    @Value("${app.server.host.login_url}")
    private String appServerLoginUrl;
    //APP退出地址(相对路径)  /logout
    @Value("${app.server.host.logout_url}")
    private String appServerLogoutUrl;
}

@Configuration
@EnableWebSecurity //启用web权限
@EnableGlobalMethodSecurity(securedEnabled = true) //启用方法验证
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 引入自定义配置信息
     */
    @Autowired
    private CasProperties casProperties;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.authenticationProvider(casAuthenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //禁用csrf保护机制
        http.csrf().disable();
        //禁用cors保护机制
        http.cors().disable();
        //禁用form表单登录
        http.formLogin().disable();
        //增加自定义过滤器
        http.exceptionHandling()
                .authenticationEntryPoint(casAuthenticationEntryPoint()) //CAS认证入口点
                .and()
                .addFilterAt(casAuthenticationFilter(), CasAuthenticationFilter.class)//在指定筛选器类的位置添加筛选器
                .addFilterBefore(logoutFilter(), LogoutFilter.class) //在xxx之前添加过滤器
                .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);//在xxx之前添加过滤器
    }

    /**
     * CAS认证入口点开始 =============================================================================
     */
    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
        CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());//CAS登录地址(绝对路径)   ${cas.server.host.url}/login
        casAuthenticationEntryPoint.setServiceProperties(serviceProperties());//资源端配置信息: APP服务地址(绝对路径) http://localhost:9001 + APP登录地址(相对路径)  /login
        return casAuthenticationEntryPoint;
    }

    @Bean
    public ServiceProperties serviceProperties() {
         //APP配置信息(资源端)
        ///APP服务地址(绝对路径) http://localhost:9001 + APP登录地址(相对路径)  /login
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService(casProperties.getAppServerUrl() + casProperties.getAppServerLoginUrl());
        serviceProperties.setAuthenticateAllArtifacts(true);
        return serviceProperties;
    }
    /**
     * CAS认证入口点结束 =============================================================================
     */

    /**
     * CAS认证过滤器开始 =============================================================================
     */
    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppServerLoginUrl());//APP登录地址(相对路径)  /login
        return casAuthenticationFilter;
    }

    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        //初始化CAS认证业务逻辑提供者
        CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
        casAuthenticationProvider.setAuthenticationUserDetailsService(userDetailsByNameServiceWrapper());//认证用户详细信息业务逻辑
        casAuthenticationProvider.setServiceProperties(serviceProperties());//设置资源地址: APP服务地址(绝对路径) http://localhost:9001 + APP登录地址(相对路径)  /login
        casAuthenticationProvider.setTicketValidator(new Cas20ServiceTicketValidator(casProperties.getCasServerUrl()));//设置CAS服务地址(绝对路径)  http://localhost:8080/cas
        casAuthenticationProvider.setKey("an_id_for_this_auth_provider_only");
        return casAuthenticationProvider;
    }

    @Bean
    public UserDetailsByNameServiceWrapper userDetailsByNameServiceWrapper() {
        UserDetailsByNameServiceWrapper userDetailsByNameServiceWrapper = new UserDetailsByNameServiceWrapper();//认证用户详细信息包装类
        userDetailsByNameServiceWrapper.setUserDetailsService(userDetailsService());//设置认证业务逻辑具体实现
        return userDetailsByNameServiceWrapper;
    }

    @Override
    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsServiceImpl();
    }
    /**
     * CAS认证过滤器结束 =============================================================================
     */


    /**
     * CAS登出过滤器开始 =============================================================================
     */
    @Bean
    public LogoutFilter logoutFilter() {
        //  CAS退出地址(绝对路径)   ${cas.server.host.url}/logout?service=${app.server.host.url}
        LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler());
        //    APP退出地址(相对路径)  /logout
        logoutFilter.setFilterProcessesUrl(casProperties.getAppServerLogoutUrl());
        return logoutFilter;
    }

    @Bean
    public SingleSignOutFilter singleSignOutFilter() {
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setIgnoreInitConfiguration(true);
        return singleSignOutFilter;
    }
    /**
     * CAS登出过滤器结束 =============================================================================
     */
}

7.编写控制器类

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

8.启动项目测试

  1. 在浏览器输入地址进行访问:http://localhost:9001/order/info ,发现报错了,报错的原因很简单,zhangsan不能访问订单,只有lisi可以。
    在这里插入图片描述

  2. 使用退出链接 http://localhost:9001/logout 进行退出
    在这里插入图片描述

使用lisi进行重新访问:http://localhost:9001/order/info
在这里插入图片描述
登录以后,我们就可以看到我们的业务逻辑执行后所返回的数据了。

在这里插入图片描述

六. SpringBoot-jar的方式启动 cas-server

<?xml version="1.0" encoding="UTF-8"?>
<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>org.apereo.cas</groupId>
    <artifactId>cas-overlay</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>

    <properties>
        <cas.version>5.3.16</cas.version>
        <mysql.version>8.0.23</mysql.version>

        <!-- 这个 main-class 不是设置启动类,而是设置 springboot 的加载方式 -->
        <main-class>org.springframework.boot.loader.WarLauncher</main-class>
    </properties>

    <dependencies>
        <!-- 官方 webapp,记得把 overlays 文件夹下的 lib 目录的 jar 包添加到类路径,并设置作用于为 provider -->
        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-webapp-tomcat</artifactId>
            <version>${cas.version}</version>
            <type>war</type>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-support-jdbc</artifactId>
            <version>${cas.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>net.shibboleth.tool</groupId>
                    <artifactId>xmlsectool</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-support-jdbc-authentication</artifactId>
            <version>${cas.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>net.shibboleth.tool</groupId>
                    <artifactId>xmlsectool</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-core-services-api</artifactId>
            <version>${cas.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>cas-server</finalName>
        <plugins>
            <!-- 借助 springboot 打包插件重新打包,否则无法直接运行 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.7.RELEASE</version>
                <configuration>
                    <!-- 这里设置真正的启动类 -->
                    <mainClass>org.apereo.cas.web.CasWebApplication</mainClass>
                    <excludes>
                        <!-- 打包时排除自身 -->
                        <exclude>
                            <groupId>org.apereo.cas</groupId>
                            <artifactId>cas-server-webapp-tomcat</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <archiveClasses>false</archiveClasses>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <overlays>
                        <!-- 整合 webapp -->
                        <overlay>
                            <groupId>org.apereo.cas</groupId>
                            <artifactId>cas-server-webapp-tomcat</artifactId>
                        </overlay>
                    </overlays>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
java -jar cas-server.war

七.cas.properties配置项介绍


1、cas.securityContext.status.allowedSubnet=127.0.0.1
  可以访问的服务端统计页面:http://sso.jadyer.com:8080/cas-server-web/status
  可以访问的服务端统计页面:http://sso.jadyer.com:8080/cas-server-web/statistics

2、host.name=S3
  uniqueIdGenerators.xml中的各种UniqueTicketIdGenerator生成TGT/ST等ticket时会用到host.name作为ticket的后缀
  host.name通常用在集群环境下,其值对于每个节点来说都必须是唯一的,这样整个集群环境生成的各种ticket也必定是唯一的
  单机环境下就没必要修改它了

3、slo.callbacks.disabled=false:是否禁用单点登出
4、cas.logout.followServiceRedirects=true:是否允许客户端Logout后重定向到service参数指定的资源


5、tgt.maxTimeToLiveInSeconds=28800 指的是TGT(Session)的最大有效时间,默认28800s,即8小时
   tgt.timeToKillInSeconds=7200  指在用户没有对系统进行任何操作的情况下,7200秒之后,也就是两个小时之后TGT会过期。过期之后需要重新登录操作。



6、st.timeToKillInSeconds=10    指定ServiceTicket的有效时间,默认10s
   st.numberOfUses=1    指的是ST可以用几次才过期,默认是用过一次就过期。
  说明当你访问一个应用系统时,cas server签发了一张票据,需在十秒钟之内拿ST去server进行校验,过了10秒钟就过期了,系统也就访问不了
    但从Cas Server生成service ticket返回给Cas client应用,到Cas client应用发送service ticket到Cas Server进行验证这个过10秒已经足够。
  这也是debug追踪CAS应用认证过程中经常会失败的原因,因为追踪的时候ServiceTicket已经过了10秒有效期了

CAS单点登录开源框架解读
前后端分离模式下 CAS 单点登录实现方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022年程序员“生存报告”出炉,仅23%月薪不足1万,你在什么段位?

转眼2022年仅剩2个月&#xff0c;在充满未知的这一年&#xff0c;程序员群体的职场现状如何&#xff1f; 近日&#xff0c;拉勾招聘数据研究院对程序员群体开展深度调研后&#xff0c;发布了一份《2022程序员群体职场洞察报告》&#xff08;以下简称报告&#xff09;&#xff…

深入理解 MultipartFile 处理文件

在Java中处理文件向来是一种不是很方便的操作&#xff0c;然后随着Spring框架的崛起&#xff0c;使用Spring框架中的MultipartFile来处理文件也是件很方便的事了&#xff0c;今天就为大家带来剖析MultipartFile的神秘面纱。MultipartFile本身并没有很复杂的结构&#xff0c;也正…

DBCO点击试剂特点:DBCO-PEG12-OH,DBCO-PEG12-Tos,DBCO-TCO

DBCO 试剂是一类点击化学标记试剂&#xff0c;含有非常活泼的 DBCO&#xff08;&#xff08;二苯并环辛炔&#xff09;基团&#xff0c;DBCO 试剂可以通过无铜点击化学与叠氮化物标记的分子或生物分子发生反应。DBCO 点击化学可以在水性缓冲液中运行&#xff0c;也可以在有机溶…

pyinstaller打包python脚本为exe可执行文件实例:错误排查小脚本

根据TIOBE全球编程语言排名&#xff0c;python是目前世界排名第一的编程语言。考虑到代码及数据的保密性&#xff0c;以及其他人电脑上可能没有装python环境&#xff0c;因此我们需要将自己编写的python脚本打包成exe格式的可执行文件发送给其他人使用。小编推荐一款名为pyinst…

Spring Boot 2.7.5 整合 Swagger 3 实现可交互的后端接口文档

文章目录前言集成访问代码参考文献前言 问: 什么是 OpenAPI? 答: OpenAPI 规范&#xff08;OAS&#xff09;&#xff0c;是定义一个标准的、与具体编程语言无关的RESTful API的规范。OpenAPI 规范使得人类和计算机都能在“不接触任何程序源代码和文档、不监控网络通信”的情…

智能音箱中采用的数字音频功放

智能改变生活&#xff0c;随高科技的发展智能科技已经融入我们生活当中&#xff0c;智能家居和IOT物联网的发展越来越深入人心&#xff0c;从手机到家电在到家居因为智能化而都在慢慢的改变&#xff1b;智能音响&#xff0c;足不出户&#xff0c;看尽大千世界&#xff1b;一屋一…

《RO 仙境传说》 Game Jam 获奖名单公布!

一睹获胜者的作品吧&#xff5e; 《RO 仙境传说》Game Jam 已经圆满结束&#xff01;许多社区成员都创造了非常棒的体验。 祝贺所有获奖者&#xff0c;并感谢每一位参与并分享了想法的用户。 接下来将公布综合优秀奖、最佳创意奖和最佳设计奖的得主&#xff01;获奖名单是由 Th…

第 21 章 InnoDB Cluster

第21章 InnoDB Cluster 文章目录第21章 InnoDB Cluster本章介绍 MySQL InnoDB Cluster &#xff0c;它整合了 MySQL 多项技术&#xff0c;使您能够部署和管理 MySQL 的完整集成的高可用解决方案。本内容是 InnoDB Cluster 的高级概述&#xff0c;有关完整文档&#xff0c;请参阅…

面试了个阿里P7程序员,他让我见识到什么才是“精通高并发与调优”

蓦然回首自己做开发已经十年了&#xff0c;这十年中我获得了很多&#xff0c;技术能力、培训、出国、大公司的经历&#xff0c;还有很多很好的朋友。但再仔细一想&#xff0c;这十年中我至少浪费了五年时间&#xff0c;这五年可以足够让自己成长为一个优秀的程序员&#xff0c;…

二叉树操作集锦(递归遍历,非递归遍历,求深度,结点个数,完全二叉树等)

二叉树操作集锦&#xff08;递归遍历&#xff0c;非递归遍历&#xff0c;求深度&#xff09; 二叉树操作集锦&#xff08;递归遍历&#xff0c;非递归遍历&#xff0c;求深度&#xff09;一、二叉树操作集锦1.1 二叉树定义1.2 二叉树创建1.3 二叉树遍历1.3.1 二叉树递归遍历1.3…

【JAVA程序设计】基于SSM的电影院在线购票系统-沙箱支付

基于SSM的电影院在线购票系统-沙箱支付项目获取项目简介开发环境项目技术功能结构运行截图项目获取 获取方式&#xff08;点击下载&#xff09;&#xff1a;是云猿实战 项目经过多人测试运行&#xff0c;可以确保100%成功运行。 项目简介 本项目是基于SSM的影院购票系统,本项…

【花雕动手做】有趣好玩的音乐可视化系列项目(32)--P10矩阵LED单元板

偶然心血来潮&#xff0c;想要做一个音乐可视化的系列专题。这个专题的难度有点高&#xff0c;涉及面也比较广泛&#xff0c;相关的FFT和FHT等算法也相当复杂&#xff0c;不过还是打算从最简单的开始&#xff0c;实际动手做做试验&#xff0c;耐心尝试一下各种方案&#xff0c;…

线程,互斥锁,临界区

目录1.线程概念2.windows的线程和linux的线程的区别3虚拟地址到地址空间的转换4.线程优缺点1.优点2.缺点5.进程控制1.创建线程2.线程出现异常了怎么办&#xff1f;进程健壮性问题3.join的第二参数如何理解4.线程终止时6.如果理解pthread_t7.三个概念6.互斥锁1.关于临界区的一点…

【设计模式】 - 结构型模式 - 装饰者模式

装饰者模式 概述 指在不改变现有对象结构的情况下&#xff0c;动态地给该对象增加一些职责&#xff08;即增加其额外功能&#xff09;的模式。 装饰者与被装饰者拥有共同的超类&#xff0c;继承的目的是继承类型&#xff0c;而不是行为 结构 Component&#xff1a;可以是接…

膜拜,Alibaba最新发布SprinBoot:进阶原理实战与面试题分析指南

为什么要写这本书&#xff1f; 我们知道&#xff0c;Spring Boot是一个集成性的开源框架&#xff0c;内部整合了很多第三方组件和框架。这些组件和框架应用如此之广泛&#xff0c;以至于大家反而往往对如何更好地使用Spring Boot自身的功能特性并不是很重视。事实上&#xff0…

CubeMX+VSCode+Ozone的STM32开发工作流(一)背景知识介绍

neozng1hnu.edu.cn TODO&#xff1a;1. 添加一键编译启用ozone调试/一键编译下载的脚本&#xff0c;使得整个进一步流程自动化2. 增加更多的背景知识介绍3. 增加VSCode下RTT viewer的支持和一键下载(不进入调试)的支持前言 了解过嵌入式开发的你一定接触过Keil&#xff0c;这款…

[附源码]java毕业设计校园求职与招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

单克隆抗体WuT9/甘草次酸-氟尿嘧啶偶联顺铂/RGD肽修饰聚谷氨酸-顺铂复合物的制备

小编下面整理了单克隆抗体WuT9/甘草次酸-氟尿嘧啶偶联顺铂/RGD肽修饰聚谷氨酸-顺铂复合物的制备&#xff0c;来看&#xff01; RGD肽修饰聚谷氨酸-顺铂复合物制备&#xff1a; 以改性聚谷氨酸侧链羧基与顺铂稳定配位,再与RGD肽进行化学偶联,得到修饰后的药物复合物,对复合物的…

【Java基础】HashMap扩容 | CopyOnWriteArrayList 的底层原理 | 字节码 | Java 异常体系

1. HashMap的扩容机制 JDK 1.7 扩容是针对数组进行扩容&#xff0c;链表是不需要进行扩容的。扩容时先生成原来数组两倍大小的新数组&#xff0c;在把原来老数组上的链表上的元素转移过去。具体在转移链表中元素的步骤是&#xff1a;取每个元素的 key&#xff0c;基于新数组长…

Java反射学习笔记--使用示例

简介 反射是Java编程语言中的一个特性。它允许执行的Java程序 检查 或 操作 自身&#xff0c;并操作程序的内部属性。例如&#xff0c;Java类可以获取其所有成员的名称并显示它们。 反射的一个具体用途是在JavaBeans中&#xff0c;软件组件可以通过一个构建工具进行可视化操作…