我正在使用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 =“你的会话已经过期”
答案 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}}。