`
y806839048
  • 浏览: 1126070 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

cas的session存储及实现共享的

    博客分类:
  • cas
cas 
阅读更多

 

cas的session存储及实现共享的原理:

cas在HashMapBackedSessionMappingStorage存session所以后面可以根据自己的tic,结合cookie反向生成session放到新的web服务器中

集群思想:cas通过redis覆写可以实现多节点cas的集群(都是用redis存储session,不再使用HashMapBackedSessionMappingStorage这个内部的map存)

 

 

 

cas是开源的登录认证方案,可以实现多个web应用的单点登录。

随着用户量的增加,web应用需要部署多个实例,要实现不同应用、多实例的共享session,需要先了解cas的logout机制。简单的说,web应用在接入cas的时候需要继承cas-client-core,这个模块完成的事情如下:

 

  • 拦截到web应用的请求,验证登录状态,若未登录则跳转到登录页
  • 登录成功,web应用的tomcat存储session,cas-server保存TGT信息,cas-client-core保存ST和session的对应关系
  • 登出时由cas-server返回ST信息,cas-client-core根据ST删除自己存储在内存的ST和session信息
要实现共享session,就需要解决以下两个问题:
  • tomcat共享session
  • cas-client-core共享ST和session的对应关系

tomcat共享session

tomcat默认的session是存在在内存的,因此要实现共享就需要实现session存储到数据库,考虑到用户操作需要频繁读取session,因此redis很适合用来实现session统一存储。
tomcat-redis-session-manager是开源的tomcat共享session插件,这里需要注意要下载比较新的master版本,我当时是下了稳定版本tomcat-redis-session-manager-1.2-tomcat-7-java-7,结果一直在死循环,阅读源码才修改了其中的bug,后面发现master已经修复bug。
我用的插件版本如下:
  • commons-pool-1.6.jar
  • jedis-2.0.0.jar
  • 修改bug后的tomcat-redis-session-manager-1.2-tomcat-7-java-7.jar
然后按照官网的说明,只需要在tomcat的context.xml简单加上配置就ok

cas-client-core共享ST和session

cas-client-core利用HashMapBackedSessionMappingStorage实现了ST和session的内存存储,因此很简单,我们只需要实现使用redis存储ST和session的缓存,替换该接口即可。
这里在序列化存储的时候碰到头疼的问题,StandardSessionFacade没有实现序列化,如果改动StandardSessionFacade需要重新编译catalina的jar包,比较麻烦所以没有选择该方案。
那怎么办呢?在集成了tomcat-redis-session-manager插件后,tomcat使用的session最终实例其实还是RedisSession,这个必然实现了序列化接口,因此我们只需要存储这个实例即可。问题来了,StandardSessionFacade的变量session为private,真是处处坑。。只能用java反射来获取了。以下是redis保存ST和session的源码:
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public void addSessionById(String mappingId, HttpSession session) {  
  3.     String STKey = getKey(mappingId);  
  4.     StandardSessionFacade standardSessionFacade = (StandardSessionFacade) session;  
  5.     RedisSession redisSession = null;  
  6.     try {  
  7.         redisSession = (RedisSession) getValue(standardSessionFacade, "session");  
  8.     } catch (IllegalAccessException e) {  
  9.         e.printStackTrace();  
  10.     } catch (NoSuchFieldException e) {  
  11.         e.printStackTrace();  
  12.     }  
  13.     if (null == redisSession) {  
  14.         log.error("get redisSession fail");  
  15.         return;  
  16.     }  
  17.   
  18.     sessionRedisTemplate.opsForValue().set(STKey, jdkSerializer.serialize(redisSession));  
  19.     String sessionKey = getKey(session.getId());  
  20.     stringRedisTemplate.opsForValue().set(sessionKey, STKey);  
  21.     log.debug("cas-client add session, mappingId:" + mappingId + " sessionId:" + session.getId());  
  22. }  
保存ok了,接下来看看删除,先来看看SingleSignOutHandler的删除代码:
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public void destroySession(final HttpServletRequest request) {  
  2.     final String logoutMessage = CommonUtils.safeGetParameter(request, this.logoutParameterName);  
  3.     if (log.isTraceEnabled()) {  
  4.         log.trace("Logout request:\n" + logoutMessage);  
  5.     }  
  6.   
  7.     final String token = XmlUtils.getTextForElement(logoutMessage, "SessionIndex");  
  8.     if (CommonUtils.isNotBlank(token)) {  
  9.         final HttpSession session = this.sessionMappingStorage.removeSessionByMappingId(token);  
  10.   
  11.         if (session != null) {  
  12.             String sessionID = session.getId();  
  13.   
  14.             if (log.isDebugEnabled()) {  
  15.                 log.debug("Invalidating session [" + sessionID + "] for token [" + token + "]");  
  16.             }  
  17.             try {  
  18.                 session.invalidate();  
  19.             } catch (final IllegalStateException e) {  
  20.                 log.debug("Error invalidating session.", e);  
  21.             }  
  22.         }  
  23.     }  
  24. }  
invalidate方法会调用StandardSession的expire方法,此处需要利用manager获取上下文信息,但是manager无法存储(测试过使用json序列化或者java 序列化均无法存储manager),因此invalidate不会真正去执行,看了下代码,只是通知一些监听者。so,感觉问题不大,ST和session对应关系信息删除了,接下来就是删除tomcat的session,干脆用了比较trick的方法,在cas-client-core直接删除tomcat的session。附上删除的代码:
 
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public HttpSession removeSessionByMappingId(String mappingId) {  
  3.     String STKey = getKey(mappingId);  
  4.     log.debug("cas-client remove session, STKey:" + STKey);  
  5.     RedisSession session = null;  
  6.     byte[] value = (byte[]) sessionRedisTemplate.opsForValue().get(STKey);  
  7.     session = (RedisSession) jdkSerializer.deserialize(value);  
  8.     if (null == session) {  
  9.         log.error("session is null");  
  10.         return null;  
  11.     }  
  12.   
  13.     removeBySessionById(session.getId());  
  14.     sessionRedisTemplate.delete(session.getId());  
  15.     log.debug("delete session:" + session.getId());  
  16.   
  17.     return session;  
  18. }  
  19.   
  20. @Override  
  21. public void removeBySessionById(String sessionId) {  
  22.     log.debug("Attempting to remove Session=[" + sessionId + "]");  
  23.     String sessionKey = getKey(sessionId);  
  24.     String st = stringRedisTemplate.opsForValue().get(sessionKey);  
  25.   
  26.     if (log.isDebugEnabled()) {  
  27.         if (st != null) {  
  28.             log.debug("Found mapping for session.  Session Removed.");  
  29.         } else {  
  30.             log.debug("No mapping for session found.  Ignoring.");  
  31.         }  
  32.     }  
  33.     stringRedisTemplate.delete(sessionKey);  
  34.     sessionRedisTemplate.delete(st);  
  35. }  
实现有点trick,测试暂时没有发现问题,两个实例能够正常登陆、使用和退出。

 

分享到:
评论

相关推荐

    CASClient集群环境的Session问题及解决方案.docx

    CASClient 集群环境的 Session 问题及解决方案 本文将详细介绍 CASClient 集群环境中的 Session 问题及解决方案。CASClient 是一种开源的单点登录系统,能够提供统一的登录和注销机制。但是在集群环境中应用 CAS...

    PHP实现多服务器session共享之memcache共享.rar

    PHP的memcache扩展提供了一个解决方案,它是一个高性能的分布式内存对象缓存系统,常被用来作为session存储后端。通过配置php.ini文件,可以将session的存储机制从默认的文件系统改为memcache服务器集群。 具体实现...

    CAS实现原理与例子

    CAS系统会将用户的认证信息存储在Cookie或Session中,以便在用户访问不同的应用系统时,自动进行认证。 二、CAS单点登录系统的优点 CAS单点登录系统的优点主要包括: * 减少用户在不同系统中登录耗费的时间,减少...

    session过期问题

    在Web开发中,Session是服务器用来跟踪用户状态的一种机制,它是服务器端存储用户信息的方式。在用户登录后,服务器会创建一个Session,并将用户的登录信息(如用户ID、用户名等)存储在这个Session对象中,然后将...

    cas4.1.x集成mysql,ldap,redis(session和票据),写了简单的两个客户端demo

    - 会话管理:通过将用户的会话信息序列化并存储在Redis中,可以实现跨服务器的会话共享,提高系统的可扩展性。 - 票据管理:TGT是CAS SSO机制的核心,用于生成后续的服务票据(Service Ticket)。将TGT存储在Redis...

    Tomcat 同一服务器上 不同web项目共享session的

    这样,所有的Web应用都会使用同一个session存储,达到共享目的。例如,可以创建一个全局的`GlobalNamingResources`,并在各个应用中引用它。 5. **使用分布式session**:如果在集群环境中,可以使用如Memcached、...

    处理session跨域几种方案

    2. **统一Session存储**: - **数据库存储**:文中提供的`Session`类示例展示了如何将Session数据存储在MySQL数据库中。这种方法适用于多台服务器或跨域情况,因为数据存储在集中式位置。但需要注意,频繁的Session...

    spring boot整合redis实现shiro的分布式session共享的方法

    Spring Boot 整合 Redis 实现 Shiro 的分布式 Session 共享 Shiro 是一个优秀的 Java 安全框架,提供了强大的身份验证、授权和会话管理功能。然而,在分布式架构中,Shiro 的会话管理机制需要进行特殊处理,以便...

    cas spnego认证方式(即加ad域的windows主机应用免登录)高可用集群方案(目前来看国内第一份资料,本人探索出来的)

    3. **设置Ticket共享**:推荐使用Redis作为Ticket的存储介质,确保Ticket数据能在所有CAS服务器间共享。 4. **部署Nginx负载均衡器**:配置Nginx作为前端负载均衡器,负责将外部请求分发至后端的CAS服务器集群。 #...

    cas的部署规则

    - `test1`接收到来自CAS服务器的重定向请求后,检查TGC中存储的TGT是否与其自身session中存储的TGT一致。如果不一致,则`test1`会向CAS服务器发送ST进行验证。 - CAS服务器验证ST的有效性后,确认用户身份无误,并将...

    PHP实现SSO单点登录三种情况的实现方式详解编程小技巧共

    1. **集中式Session存储**:所有应用的Session信息都存储在一个集中的存储系统(如Redis或Memcached)中,而不是本地Session。 2. **Session ID匹配**:用户登录后,CAS会生成一个全局的Session ID,并分配给所有...

    单点登录cas应用

    CAS(Central Authentication Service)是实现SSO的一种开源协议,它提供了一个中心认证服务器和一组标准化的接口,使得不同的应用系统能够共享同一个认证服务。 在SSO系统中,Cookie是实现跨域身份验证的关键。当...

    CI框架Session.php源码分析

    同时,CI的Session机制还支持数据库存储,使得在多服务器环境下更容易共享session数据,提高了系统的可扩展性。 总的来说,CI框架的Session组件通过自定义的实现,提供了一套强大而灵活的session管理方案,结合了...

    jsp如何实现单点登录

    在JSP中,实现SSO的关键在于正确管理和共享Cookie与Session。Cookie是客户端存储的信息,而Session是服务器端存储的信息。登录成功后,服务器会在用户的浏览器上设置一个全局Cookie,并在Session中保存相应的用户...

    详解Django CAS 解决方案

    它通过将认证信息集中存储在服务端(即CAS服务器),来实现子系统间的登录状态共享。一旦用户通过CAS服务器认证,他或她就可以访问其他配置了CAS认证的子系统,而无需再次登录。 知识点二:Django CAS解决方案的...

    springboot+shiro+redis整合

    将SpringBoot、Shiro和Redis整合,主要目的是利用Shiro进行用户认证和授权,而Redis作为Session的共享存储,解决分布式环境下的会话一致性问题。以下是整合步骤: 1. **引入依赖**:在SpringBoot的pom.xml文件中...

    x-uni-session:单点登录session服务端

    2. **Session管理**:在X-uni-session中,session服务端负责存储和管理用户登录状态。每个用户登录时,会在服务器上创建一个session对象,其中包含用户的唯一标识和其他相关信息。通过session,服务端可以追踪用户的...

    singleLogin.rar

    通过解压并研究"singleLogin"文件,你可以更深入地理解如何在实际项目中整合SSO功能,包括SSM框架的使用、Spring Security的配置、以及Redis作为session共享的实现细节。这将有助于提升你的SSO实施能力,同时对...

Global site tag (gtag.js) - Google Analytics