文档章节

shiro cas 单点登录 两个cas client,一个登出另外一个没登出

110hxl
 110hxl
发布于 2016/12/09 11:58
字数 756
阅读 9
收藏 0

问题表现:两个站点使用同一个cas单点登录,登录后,在A系统登出,B系统也同时登;而在B系统登出A系统未登出;

问题原因:A系统没有实现cas的logout逻辑。需要实现logoutFilter逻辑;在请求cas.example.com/cas/logout时,Cas Server会将客户端携带的TGT删除,同时回调该TGT对应的所有service;所以cas client需要实现登出逻辑,使会话失效;

参考:http://elim.iteye.com/blog/2144265

 

-----------------------------------------------我来分隔-----------------------------------------------------

一开始并不知道这套逻辑;只从表现出来的差异去查找。

表现:在A系统登出,再去刷新B系统页面;会得到一个新的JSESSIONID, 也就是服务端把当前连接当成新的会话;

查找JSESSIONID的生成代码。一开始想到应该是tomcat生成的,所以根据http://stackoverflow.com/questions/595872/under-what-conditions-is-a-jsessionid-created;提供的说法,在调用request.getSession()或request.getSession(true)时触发是否生成JSESSIONID(根据请求头是否带有JSESSIONID的cookie);其中找到:

JSESSIONID这个字符串值定义在: tomcat-embed-core.jar下的org.apache.catalina.util.SessionConfig类下的一个常量属性;

把JSESSIONID植入cookie的是 org.apache.catalina.connector.Request类的doGetSession方法;

如果使用了Shiro,shiro会拦截以上步骤,覆盖为自己的实现;

shiro中也默认是JSESSIONID,定义在org.apache.shiro.web.servlet.ShiroHttpSession类下的属性;

session生成是org.apache.shiro.web.session.mgt.DefaultSessionManager类的create方法;

cookie的生成是在org.apache.shiro.web.session.mgt.DefaultSessionManager类的storeSessionId方法;

shiro的seesionId默认使用的是UUID.randomUUID()方法;

shiro会在认证失败(会先获取当前session,并判断是否已认证)的拦截器的onAccessDenied()方法中调用saveRequestAndRedirectToLogin(...).保存当前请求到新session.并且跳转到cas登录页

-------------------------------------------下面是logoutFilter的实现逻辑----------------------------------

   /**
     * 拦截所有请求
     * --如果请求中包含了ticket参数(成功登陆cas后,cas server会自动跳转到cas client并在url中带上ticket),
     *   记录ticket和sessionID的映射
     *
     * --如果请求中包含logoutRequest参数(说明是cas logout, cas server回调ticket相同的所有cas client),
     *   标记session为无效 如果session不为空,且被标记为无效,则登出
     *
     * @param request  the incoming ServletRequest
     * @param response the outgoing ServletResponse
     * @return 是logoutRequest请求返回false,否则返回true
     * @throws Exception if there is any error.
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest req = (HttpServletRequest) request;
        if (handler.isTokenRequest(req)) {
            // 是否是登陆成功的回调。请求链接中含有ticket参数,记录ticket和sessionID
            handler.recordSession(req);
            return true;
        } else if (handler.isLogoutRequest(req)) {
            // cas服务器发送的请求,链接中含有logoutRequest参数,在之前记录的session中设置logoutRequest属性为true
            // 因为Subject是和线程是绑定的,所以无法获取登录的Subject直接logout
            handler.invalidateSession(req);
            // Do not continue up filter chain
            return false;
        } else {
            logger.trace("Ignoring URI " + req.getRequestURI());
        }
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(false);
        if (session != null && session.getAttribute(handler.getLogoutParameterName()) != null) {
            //如果session存在,且属性中有logoutRequest值,则登出
            try {
                subject.logout();
            } catch (SessionException ise) {
                logger.debug("Encountered session exception during logout.  This can generally safely be ignored.",
                        ise);
            }
        }
        return true;
    }

 

© 著作权归作者所有

共有 人打赏支持
110hxl
粉丝 6
博文 193
码字总数 48724
作品 0
深圳
程序员
CAS 4.1.x 单点登出(退出登录)的原理解析

我们在项目中使用了cas作为单点登录的解决方案,当在集成shiro做统一权限控制的时候,发现单点退出登录有坑,所以啃了一下CAS的单点登出的源码,在此分享一下。 1、回顾单点登录中一些关键事...

细肉云吞
2017/07/19
0
0
单点登录 CAS4.0 服务器端配置

CAS 介绍 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点: 开源的企业级单点登...

deepler
2016/07/22
133
0
Spring Shiro CAS 客户端集成配置

如果不熟悉Shiro 和CAS的概念,可以在网上搜索一下这方面的资料, 在配置CAS客户端配置之前,首先要进行CAS服务端配置 配置之前需要引入一些jar包具体如下: (一)cas登录 web.xml配置 shir...

zbbmaster
2017/05/12
0
0
Shiro之CAS单点登录-yellowcong

配置单点登录,有点坑的是,我将Session存在了缓存中,导致我每次登录的时候,都不去cas验证中心,我就感觉很无语,后来将sessionManager删除后,就好用了,太坑了,这问题坑了一天多。实现C...

yelllowcong
2017/12/21
0
0
单点登录CAS使用记:关于服务器超时以及客户端超时的分析

我的预想情况 一般情况下,当用户登录一个站点后,如果长时间没有发生任何动作,当用户再次点击时,会被强制登出并且跳转到登录页面, 提醒用户重新登录。现在我已经为站点整合了CAS,并且已...

Zzzz_WP
09/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
4
0
现场看路演了!

HiBlock
昨天
12
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
9
0
官方精简版Windows10:微软自己都看不过去了

微软宣布,该公司正在寻求解决方案,以减轻企业客户的Windows 10规模。该公司声称,企业客户下载整个Windows 10文件以更新设备既费钱又费时。 微软宣布,该公司正在寻求解决方案,以减轻企业...

linux-tao
昨天
15
0
TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部