cas客户端无法退出问题解决

记录grails3项目中使用spring security cas插件遇到的单点登出问题。
依据文档进行cas相关配置。测试发现cas客户端退出后,其他cas客户端依然是登录状态,本文记录解决这个问题的过程。

  1. 首先想到的是,客户端1退出的时候是否没有通知到cas服务端。
    验证:在自定义的TGTDestoryEventListener类中加上断点。
    结果:进入断点,cas接收到客户端的退出申请,进行了销票操作。


    image.png
  2. 既然cas服务已经进行了销票操作,那是不是没有把退出的消息通知到登录的客户端呢,继续验证。
    验证:在DefaultLogoutManager的performLogout中加入断点,查看是否得到logoutReuqest。
    结果:得到logoutRequests,所以cas已经成功发出通知。


    image.png
  3. cas服务已经发出了通知,那么问题就在cas客户端了。
    查看spring security cas源码,是由SingleSignOutFilter接收cas服务端发出的注销session请求的,具体操作由SingleSignOutHandler完成。
    在SingleSignOutHandler中,当登录成功的时候会将ST和session一块存入sessionMappingStorage中,当收到退出申请的时候,从sessionMappingStorage中找到对应session,进行invalidate操作。
    验证:是否进行session.invalidate()
    结果:抛出异常session already invalidate


    image.png

    多次观察发现,当进行到session.invalidate()时,session的isValid属性一直是false,所以会抛出异常。正常情况下isValid应该是true,猜测是在某一步骤将isValid置为了false。
    -- 至此思路断了,没有定位到是哪里的操作。

  4. 时隔多天再次尝试解决这个问题。
    在controller中获取sessionId,发现和sessionMappingStorage存储的是不一样的,通过F12网络观察cookies的变化,发现在登录成功之后,cookie中的sessionId发生了变化,所以猜测应该是登录成功后造成的。


    登录前

    登录成功后

查阅了spring security core插件的文档,发现了其中的一段说明,意思是登录后是否将现有会话的会话属性复制到新会话,默认是true,如下图

image.png

尝试将该功能关闭,进行验证,成功退出。。。

你可能感兴趣的:(cas客户端无法退出问题解决)