在web工程(最普通的Servlet&JSP)中使用shiro,却发现每次请求Servlet时,通过shiro获得的session id都是新的(都不一样),不知为什么?
新建了一个普通的Java Web工程,自定义了Reaml,编写一个Servlet,每次请求这个Servlet时,打印subject的Session ID,可是每次都得到不同的Session ID?为什么呢?代码哪里写错了吗?代码如下:shiro.ini[users]
zhang=123,admin
[roles]
admin=user:*
自定义realmpublic class MyRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 先不管认证
return new SimpleAuthenticationInfo("zhang", "123", this.getName());
} @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 先不管授权
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
return authorizationInfo;
}
}
上下文启动时,创建了SecurityManager@WebListener
public class MyServletContextListener implements ServletContextListener { public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("destroyed");
} public void contextInitialized(ServletContextEvent arg0) {
System.out.println("initialized"); // Cookie
SimpleCookie sessionIdCookie = new SimpleCookie();
sessionIdCookie.setName("sid"); // SessionManager
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionIdCookie(sessionIdCookie); // SecurityManager
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setSessionManager(sessionManager);
securityManager.setRealm(new MyRealm()); SecurityUtils.setSecurityManager(securityManager);
}
}
Servlet@WebServlet(name = "myServlet", urlPatterns = "/login") 
public class MyServlet  extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
      throws ServletException, IOException {  
Subject subject = SecurityUtils.getSubject();  
System.out.println("Session ID:"+subject.getSession().getId().toString());
    }
}
在浏览器输入:localhost:8080/test/login,回车,再刷新2次,控制台输出了3个不同的Session ID?这是为什么呢?Session ID:b9e3faa1-55d4-4b9d-8276-50e717f179c0
Session ID:21e14dff-1079-403d-bc9b-76bde9edbc70
Session ID:90728816-9f3c-4ead-8aee-db2644635fa9

解决方案 »

  1.   

    你输出一下SESSION的超时时间看看request.getSession().getMaxInactiveInterval()
      

  2.   

    哥们,我也是研究了很久才研究出来的,我通过看源码,发现本地的session,也就是不是web的,它不会通过cookie中的jsessionid来判断是否是登录状态,通过看源码发现,是通过将subject与当前线程绑定,来实现是否该subject已经登录,由于我们使用的是web服务器tomcat,用的是连接池,当有请求过来的时候,会有一个线程来对应响应,每次请求的对应的线程是不一样的,因为subject与线程绑定的,有的线程没有subject,会再次登录,并生成session,所以sessionid不一样,但是连接池是循环使用的,当我们多次请求的时候,你会发现sessionid有重复的,原因就是这个线程的subject之前有登录过。
    希望能看懂!