如何知道与主题关联的会话在java shiro中是否已过期

时间:2013-11-05 11:48:05

标签: java shiro

我正在使用java shiro for security.i需要在会话过期时返回消息,如果会话未过期,那么我需要返回不同的消息,例如un Authenticate user。

这是我的代码。

@GET
@Path("/{userId}")
public Response view(@PathParam("userId")String userId)
{
   ResponseBuilder builder = Response.ok();
   if(SecurityUtils.getSubject().isAuthenticated())
    {

       Registeration registeration=new Registeration();
       boolean status=registeration.getDetails(userId,builder);
       log.debug("the status is:"+status); 


    }
    else
    {
        builder.status(401).entity("You are currently not login .please Login for Access Services");

    }   
    return builder.build();     

}

以上休息服务工作正常。当用户未登录时。此方法将返回else部分的消息。但我还需要返回消息,在会话过期后,用户尝试访问此休息服务,然后我需要返回“您的会话已过期”。 但是在上面的情况下,如果会话过期,那么同样的消息和if用户也没有登录,那么同样的消息。 我不知道我将如何检查这两个条件 1)如果用户没有登录,则message =“您正在登录” 2)如果会话已经过期,那么messsage =“你的会话已经过期”

1 个答案:

答案 0 :(得分:2)

在执行了一些简单的测试之后,我相信使用SecurityUtils.getSubject().isAuthenticated()的方式在当前会话超时时无法获得正确的结果。我想这对你有用,因为第二个请求为你创建了另一个Subject而不是原始的ThreadContext.getSubject()。通过SecurityUtils.getSubject()而不是Subject获取它可以很容易地证明这一点,因为如果它为null,后者会为您创建一个新的ThreadContext.getSubject()。如果第二次请求到达您的方法并且Subject.isAuthenticated()的返回值为null,则表示它是与Shiro的新线程的新连接。

所以,我的测试结果表明,如果它是'超时'的情况,SessionListener仍然会返回true。请注意他们的文件Session Validation & Scheduling

  

出于性能原因,Sessions仅在访问时验证它们是否已被停止或过期(即subject.getSession())。这意味着如果没有额外的定期定期验证,Session孤儿就会开始填满会话数据存储。

根据您的要求,您可以实施onExpiration并在方法if(SecurityUtils.getSubject().isAuthenticated()) { Session session = SecurityUtils.getSubject().getSession(false); try { session.touch(); } catch (ExpiredSessionException e) { // timeout case. } } else { // not login case. } 中记录主体。或者您可以访问会话以在Shiro中触发验证:

session.touch()

调用lastAccessTime并不是多余的,因为它会更新{{1}},如果您从未触及代码中的会话,则不会更新{{1}}。