shiro绕过密码登录的session丢失问题



 由于项目的需要,别的平台需要单点登录到当前系统,单点登录的时候会推送一个token值过来,通过解析token值获取相关信息,由于推送过来的token只包含账号信息,是不包含密码信息的,所以就想到了绕过密码登录的方案,因为我们的项目使用了shiro安全框架,会话都交给了shiro去管理。所以就从网上搜索到了下面这样一个实现:

 

在某些应用场景下我们或许需要直接登录,而不需要用户输入密码,例如用户用手机直接登录的场景。

在Shiro中我们通过在线程变量中绑定一个已通过验证的Subject对象即可实现。

 

Java代码   收藏代码
  1. PrincipalCollection principals = new SimplePrincipalCollection(  
  2.                 user.getId(), "MobileRealm");  
  3. Builder builder = new WebSubject.Builder(  
  4.                 ServletActionContext.getRequest(),  
  5.                 ServletActionContext.getResponse());  
  6. builder.principals(principals);  
  7. builder.authenticated(true);  
  8. WebSubject subject = builder.buildWebSubject();  
  9. ThreadContext.bind(subject);  

 

以上是用于Web Application的代码,所以用的是WebSubject,应根据自己的应用选择需要创建的Subject类。

 

通过以上的方式发现有一个问题,就是发送请求构建subject的时候该请求的响应总是发送c了两个jsessionid,如下图:
c
 

 导致放到session中的值使用的会话标志是第一个sid,而第二个sid会覆盖第一个,这样就会出现session丢失的情况。

 

问题原因:

使用WebSubject.Builder构建subject的时候会产生一个sessionId,而代码中HttpSession.setAttribute()这个方法也会产生一个sessionId.因此会导致产生两个sessionId导致会话丢失的问题。

 

解决方法:

设置WebSubject.Builder的sessionid为HttpSession的Id即可,如下代码:

builder.sessionId(session.getId());

 

 

猜你喜欢

转载自tommy-lu.iteye.com/blog/2278746