在上一篇shiro-cas------整合springboot客户端实现简易的单点登陆后,我们接下来看下单点登出功能。shiro-cas-client-one系统退出,那么shiro-cas-client-two也退出。在这里我们在我们原有的界面加入退出按钮。(这里只在shiro-cas-client-one上加退出按钮,刷新shiro-cas-client-two可以登出即视为单点登出实现)

加入登出按钮后的页面:

点击退出:

发现 shiro-cas-client-one系统退出,刷新shiro-cas-client-two未退出。

经过查看源码,发现在引入的jar中没有配置登出的filter。

        <dependency><groupId>net.unicon.cas</groupId><artifactId>cas-client-autoconfig-support</artifactId><version>1.4.0-GA</version><exclusions><exclusion><groupId>org.jasig.cas.client</groupId><artifactId>cas-client-core</artifactId></exclusion></exclusions></dependency>

那么我们也实现一个自己的starter,顺便了解下springboot starter的机制。

SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。

在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配,简直不要太爽。

工作中遇到的部分场景:1、动态数据源;2、登录模块;2、基于AOP技术实现日志切面等

使用一个公用starter的时候,只需要在Maven的配置文件中添加依赖即可,这个starter可能需要依赖很多jar包,在引用这个starter的同时,依赖的jar包也会自动导入,并且SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的需要自动加载的类全路径,去加载该配置,并将Bean注入Spring Context 上下文当中。
我们也可以使用@ImportAutoConfiguration({CasAutoConfiguration.class}) 指定自动配置哪些类。
使用@SpringBootApplication(exclude = {CasAutoConfiguration.class}) 来取消自动配置。

其中 spring-boot-configuration-processor 的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给IDE使用。如当配置此jar相关配置属性在 application.properties ,你可以用ctlr+鼠标左键点击属性名,IDE会跳转到你配置此属性的类中。
关于artifactId中的名字cas-client-spring-boot-starter。Spring官方的Starter一般采取spring-boot-starter-{name} 的命名方式,如 spring-boot-starter-web 。
而非官方的Starter,官方建议 artifactId 命名应遵循{name}-spring-boot-starter 的格式。 例如:mybatis-spring-boot-starter

创建一个springboot空项目(注意版本号和引入自定义的boot版本号一致)引入依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.0.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lhl.shiro.cas</groupId><artifactId>shiro-cas-client-starter</artifactId><version>0.0.1-SNAPSHOT</version><name>shiro-cas-client-starter</name><description>Spring Boot 自定义cas starter 登录登出过滤</description><properties><java.version>1.8</java.version><skipTests>true</skipTests></properties><dependencies><!--<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.jasig.cas.client</groupId><artifactId>cas-client-core</artifactId><version>3.5.0</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>1.1.0.Final</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.5.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><!-- 配置该插件将源码放入仓库 --><plugin><artifactId>maven-source-plugin</artifactId><version>2.1</version><configuration><attach>true</attach></configuration><executions><execution><phase>compile</phase><goals><goal>jar</goal></goals></execution></executions></plugin></plugins></build>
</project>

springboot提供了一个注解@ConfigurationProperties,该注解可以完成将application.properties配置文件内的有规则的配置参数映射到实体内的field内,不过需要提供setter方法,@ConfigurationProperties注解内我们使用到了属性preffix,该属性配置了读取参数的前缀,例如serverUrlPrefix属性,对应配置文件中内容就是 cas.server-url-prefix。完整类如下:

package com.lhl.shiro.cas.client.starter.config;import javax.validation.constraints.NotNull;import org.springframework.boot.context.properties.ConfigurationProperties;/*** @author: hualiang.liu-ext* @description:* @date: created in 2021/3/2 15:13*/
@ConfigurationProperties(prefix = "cas", ignoreUnknownFields = false)
public class CasClientConfigurationProperties {/*** CAS server URL E.g. https://example.com/cas or https://cas.example. Required.* CAS 服务端 url 不能为空*/@NotNullprivate String serverUrlPrefix;/*** CAS server login URL E.g. https://example.com/cas/login or https://cas.example/login. Required.* CAS 服务端登录地址  上面的连接 加上/login 该参数不能为空*/@NotNullprivate String serverLoginUrl;/*** CAS-protected client application host URL E.g. https://myclient.example.com Required.* 当前客户端的地址*/@NotNullprivate String clientHostUrl;/*** 忽略规则,访问那些地址 不需要登录*/private String ignorePattern;/*** 自定义UrlPatternMatcherStrategy验证*/private String ignoreUrlPatternType;public String getServerUrlPrefix() {return serverUrlPrefix;}public void setServerUrlPrefix(String serverUrlPrefix) {this.serverUrlPrefix = serverUrlPrefix;}public String getServerLoginUrl() {return serverLoginUrl;}public void setServerLoginUrl(String serverLoginUrl) {this.serverLoginUrl = serverLoginUrl;}public String getClientHostUrl() {return clientHostUrl;}public void setClientHostUrl(String clientHostUrl) {this.clientHostUrl = clientHostUrl;}public String getIgnorePattern() {return ignorePattern;}public void setIgnorePattern(String ignorePattern) {this.ignorePattern = ignorePattern;}public String getIgnoreUrlPatternType() {return ignoreUrlPatternType;}public void setIgnoreUrlPatternType(String ignoreUrlPatternType) {this.ignoreUrlPatternType = ignoreUrlPatternType;}
}

其实就是cas的那几个核心filter和监听,只不过是从web.xml中移到了基于javabean配置。

package com.lhl.shiro.cas.client.starter.config;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.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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 java.util.EventListener;
import java.util.HashMap;
import java.util.Map;/*** @author: hualiang.liu-ext* @description:* @date: created in 2021/3/2 15:14*/
@Configuration
@EnableConfigurationProperties(CasClientConfigurationProperties.class)
public class CasClientConfiguration {@AutowiredCasClientConfigurationProperties configProps;/*** 配置登出过滤器* @return*/@Beanpublic FilterRegistrationBean filterSingleRegistration() {final FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new SingleSignOutFilter());// 设定匹配的路径registration.addUrlPatterns("/*");Map<String,String>  initParameters = new HashMap<String, String>();initParameters.put("casServerUrlPrefix", configProps.getServerUrlPrefix());registration.setInitParameters(initParameters);// 设定加载的顺序registration.setOrder(1);return registration;}/*** 配置过滤验证器 这里用的是Cas30ProxyReceivingTicketValidationFilter* @return*/@Beanpublic FilterRegistrationBean filterValidationRegistration() {final FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter());// 设定匹配的路径registration.addUrlPatterns("/*");Map<String,String> initParameters = new HashMap<String, String>();initParameters.put("casServerUrlPrefix", configProps.getServerUrlPrefix());initParameters.put("serverName", configProps.getClientHostUrl());initParameters.put("useSession", "true");registration.setInitParameters(initParameters);// 设定加载的顺序registration.setOrder(2);return registration;}/*** 配置授权过滤器* @return*/@Beanpublic FilterRegistrationBean filterAuthenticationRegistration() {final FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new AuthenticationFilter());// 设定匹配的路径registration.addUrlPatterns("/*");Map<String,String>  initParameters = new HashMap<String, String>();initParameters.put("casServerLoginUrl", configProps.getServerLoginUrl());initParameters.put("serverName", configProps.getClientHostUrl());if(configProps.getIgnorePattern() != null && !"".equals(configProps.getIgnorePattern())){initParameters.put("ignorePattern", configProps.getIgnorePattern());}//自定义UrlPatternMatcherStrategy 验证规则if(configProps.getIgnoreUrlPatternType() != null && !"".equals(configProps.getIgnoreUrlPatternType())){initParameters.put("ignoreUrlPatternType", configProps.getIgnoreUrlPatternType());}registration.setInitParameters(initParameters);// 设定加载的顺序registration.setOrder(3);return registration;}/*** request wraper过滤器* @return*/@Beanpublic FilterRegistrationBean filterWrapperRegistration() {final FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new HttpServletRequestWrapperFilter());// 设定匹配的路径registration.addUrlPatterns("/*");// 设定加载的顺序registration.setOrder(4);return registration;}/*** 添加监听器* @return*/@Beanpublic ServletListenerRegistrationBean<EventListener> singleSignOutListenerRegistration(){ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<EventListener>();registrationBean.setListener(new SingleSignOutHttpSessionListener());registrationBean.setOrder(1);return registrationBean;}
}

编译基于注解启动方式

第一种方式:使用自定义spring.factories的方式自动配置,步骤如下:

src/main/resource目录下创建META-INF目录,并在目录内添加文件spring.factories,给@EnableAutoConfiguration去自动扫描,具体内容如下所示:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lhl.shiro.cas.client.starter.config.CasClientConfiguration

基于spring.factories的方式配置,只需要在pom中添加依赖就可以了,项目启动,自动配置。

第二种:基于注解方式,代码如下:

package com.lhl.shiro.cas.client.starter.config;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import org.springframework.context.annotation.Import;/*** @author: hualiang.liu-ext* @description:* @date: created in 2021/3/2 15:21*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(CasClientConfiguration.class)
public @interface EnableCasClient {
}

使用时,在启动类上添加该注解,就可以了。目前为止我们的自定义starter已经配置完成,下面我们需要新建一个SpringBoot项目来测试我们的自动化配置是否已经生效。

接下来我们将定义好的starter打包编译并安装到maven仓库

然后在我们的两个客户端系统中引入自定义地starter,去除之前地starter.

        <dependency><groupId>com.lhl.shiro.cas</groupId><artifactId>shiro-cas-client-starter</artifactId><version>0.0.1-SNAPSHOT</version></dependency>

application.properties修改以下属性

#cas配置
#cas服务端前缀,不是登录地址
cas.server-url-prefix=https://shiro.sso.com:8443
#cas的登录地址
cas.server-login-url=https://shiro.sso.com:8443/login
#当前客户端的地址
cas.client-host-url=http://127.0.0.1:9010

在启动类上添加注解启动自动装配

然后重新启动两个客户端服务:

点击退出:

发现 shiro-cas-client-one系统退出,刷新shiro-cas-client-two退出。

单点登出集成成功!

参考地址:https://blog.csdn.net/qq_34021712/article/details/81486699

shiro-cas------实现单点登出并自定义登出starter相关推荐

  1. spring+shiro+cas实现单点登录,登出

    cas.war下载地址:https://download.csdn.net/download/qq_37160920/10662543 1.下载cas.war,放在tomcat的 webapps下发布 ...

  2. springboot+shiro+cas实现单点登录之shiro端搭建

    github:https://github.com/peterowang/shiro-cas 本文如有配置问题,请查看之前的springboot集成shiro的文章 1.配置ehcache缓存,在re ...

  3. cas sso单点登录 登录过程和登出过程原理说明

    CAS大体原理我就不说了,网上一大把,不过具体交互流程没说清楚,所以有这篇文章,如果有错误,请多多指教 登录过程 用户第一次访问一个CAS 服务的客户web 应用时(访问URL :http://192 ...

  4. Shiro CAS 实现单点登录

    1.简介 CAS:Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法. Shiro:Apache Shiro是一个Java安全框架,可以帮助我们完成认证.授权.会话管 ...

  5. spring + shiro + cas 实现sso单点登录

    sso-shiro-cas spring下使用shiro+cas配置单点登录,多个系统之间的访问,每次只需要登录一次,项目源码 系统模块说明 cas: 单点登录模块,这里直接拿的是cas的项目改了点样 ...

  6. 阻止window.onbeforeunload事件的弹出框 或 自定义弹出框

    前引:网上很多关于window.onbeforeunload用来监听页面的意外退出或者关闭事件的用法但都会出现下面的弹出框.为此本博客提供方案使下面弹出框消失,但又能实现自己的相应业务功能. 在使用 ...

  7. 源代码解读Cas实现单点登出(single sign out)功能实现原理

    关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理 ...

  8. java php 单点登陆,cas实现单点登录,登出(java跟php客户端)(转)

    cas实现单点登录,登出(java跟php客户端)(转)cas实现单点登录,登出(java和php客户端) (转) 最近项目中需要做单点登录,客户端包含java和php,java有几个应用程序,php ...

  9. 源代码解读Cas实现单点登出(single sign out)功能实现原理--转

    关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理 ...

最新文章

  1. PHPExcel对于Excel中日期和时间类型的处理
  2. 【Kotlin】Kotlin 类的继承 一 ( 类继承基本方式 | final 关键字 | 子类主构造函数 | 子类次构造函数 )
  3. 计算机视觉的发展现状
  4. excel常用公式整理
  5. C语言常见单链表面试题(2)
  6. java设计模式之装饰模式_Java中的装饰器设计模式
  7. Linux内核配置系统浅析
  8. Bootstrap3 表格的情景类
  9. spring 事务的实现方式和原理_spring整合atomikos实现分布式事务
  10. 想做数据化转型,为什么必须要上企业级BI?
  11. python中for循环流程图_Javascript for循环_郭隆邦技术博客
  12. linux安装gcc-c++
  13. 总结UIViewController的view在有navBar和tabBar影响下布局区域的问题
  14. three20 如何将three20中的demo添加到自己的应用程序中。
  15. 《Unix传奇》:众神的创世记
  16. python脚本实现QQ自动发送消息
  17. QScrollArea使用详解
  18. 聚播微信多开客服系统二次开发SDK服务端接口
  19. EXCEL根据两点经纬度计算距离
  20. 用matlab做音乐仿真,Matlab课程设计报告--MATLAB GUI的音乐键盘仿真

热门文章

  1. Memcache集群安装与配置
  2. Daily Scrum02 12.17
  3. python 大文件以行为单位读取方式比对
  4. 中级.NET开发人员应该知道些什么?
  5. strcat第二个参数变吗_您能解决这3个(看似)简单的Python问题吗?
  6. 高通audio数据到Speaker播放流程
  7. Baksmali用法
  8. SpringBoot之注解
  9. VSCode之调试html
  10. java中panel显示不出来_为什么我的JPanel中的某些项目没有显示?