实现CAS单点登出

2023-11-20 14:08
文章标签 实现 单点 登出 cas

本文主要是介绍实现CAS单点登出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

由于项目需求要实现单点登出需要在网上找了N久终于实现单点登出。

使用cas-server-core-3.3.3.jar(CAS Server 3.3.3)

使用cas-client-core-3.1.3.jar(CAS Client 3.1.3)

 

项目结合CAS SpringSecurity SSH

 

普通项目(没有结合Spring Security)的可以在web.xml中加入如下代码

[xhtml]  view plain copy
  1. <filter>  
  2.    <filter-name>CAS Single Sign Out Filter</filter-name>  
  3.    <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>  
  4. </filter>  
  5.   
  6. <filter-mapping>  
  7.    <filter-name>CAS Single Sign Out Filter</filter-name>  
  8.    <url-pattern>/*</url-pattern>  
  9. </filter-mapping>  
  10.   
  11. <listener>  
  12.     <listener-class>  
  13.        org.jasig.cas.client.session.SingleSignOutHttpSessionListener  
  14.     </listener-class>  
  15. </listener>  

 

 

在我们的项目中由于结合了SpringSecurity 可以将filter加入到spring Security过滤链中,也可以直接向上面的一样加入web.xml中

首先在web.xml中加入监听器。

[xhtml]  view plain copy
  1. <!-- single sign out -->  
  2. <listener>  
  3.       <listener-class>  
  4.           org.jasig.cas.client.session.SingleSignOutHttpSessionListener  
  5.       </listener-class>  
  6. </listener>  
  7. <!-- single sign out -->  

 

然后把filter加入到spring Security过滤链中

 

[xhtml]  view plain copy
  1. <!-- single sign out -->  
  2. <b:bean id="casSingleSignOutFilter" class="check.SingleSignOutFilter">  
  3.     <custom-filter before="CAS_PROCESSING_FILTER"/>  
  4. </b:bean>  
  5. <!-- single sign out -->  

 

注意上面的class="check.SingleSignOutFilter"是我自定义的filter(由于CAS3.1.3定义的SingleSignOutFilter在某种意思上没有起到作用)详情请见http://www.javaeye.com/topic/546785

自己定义一个类

[java]  view plain copy
  1. package check;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Enumeration;  
  5.   
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpSession;  
  13.   
  14. import org.apache.commons.logging.Log;  
  15. import org.apache.commons.logging.LogFactory;  
  16. import org.jasig.cas.client.session.HashMapBackedSessionMappingStorage;  
  17. import org.jasig.cas.client.session.SessionMappingStorage;  
  18. import org.jasig.cas.client.util.AbstractConfigurationFilter;  
  19. import org.jasig.cas.client.util.CommonUtils;  
  20. import org.jasig.cas.client.util.XmlUtils;  
  21.   
  22. public final class SingleSignOutFilter extends AbstractConfigurationFilter  
  23. {  
  24.   private String artifactParameterName;  
  25.   private static SessionMappingStorage SESSION_MAPPING_STORAGE = new HashMapBackedSessionMappingStorage();  
  26.   private static Log log = LogFactory.getLog(SingleSignOutFilter.class);  
  27.   
  28.   public SingleSignOutFilter()  
  29.   {  
  30.     this.artifactParameterName = "ticket";  
  31.   }  
  32.   
  33.   public void init(FilterConfig filterConfig)  
  34.     throws ServletException  
  35.   {  
  36.     setArtifactParameterName(getPropertyFromInitParams(filterConfig, "artifactParameterName""ticket"));  
  37.     init();  
  38.   }  
  39.   
  40.   public void init() {  
  41.     CommonUtils.assertNotNull(this.artifactParameterName, "artifactParameterName cannot be null.");  
  42.     CommonUtils.assertNotNull(SESSION_MAPPING_STORAGE, "sessionMappingStorage cannote be null.");  
  43.   }  
  44.   
  45.   public void setArtifactParameterName(String artifactParameterName) {  
  46.     this.artifactParameterName = artifactParameterName;  
  47.   }  
  48.   
  49.   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  
  50.     final HttpServletRequest request = (HttpServletRequest) servletRequest;     
  51.     final String logoutRequest = CommonUtils.safeGetParameter(request, "logoutRequest");     
  52.     Enumeration ff = request.getParameterNames();     
  53.     String a = request.getQueryString();     
  54.     if (CommonUtils.isNotBlank(logoutRequest)) {     
  55.          final String sessionIdentifier = XmlUtils.getTextForElement(logoutRequest, "SessionIndex");     
  56.   
  57.          if (CommonUtils.isNotBlank(sessionIdentifier)) {     
  58.             final HttpSession session = SESSION_MAPPING_STORAGE.removeSessionByMappingId(sessionIdentifier);     
  59.   
  60.             if (session != null) {     
  61.                  String sessionID = session.getId();                        
  62.                  try {     
  63.                     session.invalidate();     
  64.                  } catch (final IllegalStateException e) {     
  65.                          
  66.                  }     
  67.             }     
  68.          }     
  69.      }     
  70.          
  71.     else{     
  72.         final String artifact = CommonUtils.safeGetParameter(request, this.artifactParameterName);     
  73.         final HttpSession session = request.getSession(false);     
  74.              
  75.         if (CommonUtils.isNotBlank(artifact) && session!=null) {     
  76.             try {     
  77.                 SESSION_MAPPING_STORAGE.removeBySessionById(session.getId());     
  78.             } catch (final Exception e) {     
  79.                      
  80.             }     
  81.             SESSION_MAPPING_STORAGE.addSessionById(artifact, session);     
  82.         }     
  83.     }     
  84.   
  85.     filterChain.doFilter(servletRequest, servletResponse);     
  86.   }  
  87.   
  88.   public void setSessionMappingStorage(SessionMappingStorage storage) {  
  89.     SESSION_MAPPING_STORAGE = storage;  
  90.   }  
  91.   
  92.   public static SessionMappingStorage getSessionMappingStorage() {  
  93.     return SESSION_MAPPING_STORAGE;  
  94.   }  
  95.   
  96.   public void destroy()  
  97.   {  
  98.   }  
  99. }  

完成。

这样即可实现单点登出。(所有java应用的单点退出)

1)这样实现的效果是在登出的时候CAS Server 分发给各个客户端让各个客户端都登出,这个得让FIlter来获取,例子:一个index页面有两个链接一个指向java应用,一个指向php应用在java应用加filter 后能做出相应的动作退出动作,而对于php自己没加任何filter就没有退出。所以也得写个filter。

 

 

2)由于我们点击退出的时候请求CAS Server 而后Server分发任务让每个应用退出的消息,java程序通过filter来执行退出。PHP提供了一个phpCAS::handleLogoutRequests()来检验服务器发来的信息,

具体我们可以把这个代码放在phpbb3/include/function.php中的点击事件里面代码如下:

[php]  view plain copy
  1. if(!$admin && CAS_ENABLE){  
  2.     // initialize phpCAS   
  3.     phpCAS::client(CAS_VERSION_2_0, CAS_SERVER_HOSTNAME, CAS_SERVER_PORT, CAS_SERVER_APP_NAME);   
  4.     phpCAS::setNoCasServerValidation();   
  5.     // force CAS authentication   
  6.     phpCAS::handleLogoutRequests();//加的去看看有没有服务器端发出注销消息。  
  7.     phpCAS::forceAuthentication();   

这篇关于实现CAS单点登出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/395155

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja