我在网络应用程序中使用Apache Shiro。登录和身份验证检查工作正常,但我在实现注销/重新登录机制时遇到问题:注销是在servlet中完成的:
private void logout(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
log.debug("do logout");
Subject subject = SecurityUtils.getSubject();
subject.logout();
resp.sendRedirect("end.html");
}
但是在注销并重新登录后,我收到以下错误:
org.apache.shiro.session.InvalidSessionException: java.lang.IllegalStateException:
getAttribute: Session already invalidated
at org.apache.shiro.web.session.HttpServletSession.removeAttribute(HttpServletSession.java:167)
at org.apache.shiro.session.ProxiedSession.removeAttribute(ProxiedSession.java:135)
at org.apache.shiro.subject.support.DelegatingSubject.clearRunAsIdentities(DelegatingSubject.java:424)
at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:246)
登录按以下方式完成(在UI组件的方法中,我使用ZK作为UI框架):
private void tryLogin(UsernamePasswordToken token) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(token);
...
我不理解异常,因为来自shiro的注销使会话无效并且重新登录应该访问新会话。
答案 0 :(得分:3)
如果某人(或其他人)在调用Subject.logout()
之前使会话无效(例如httpSession.invalidate()
然后subject.logout()
),则会在版本1.2之前的Shiro中发生这种情况。
这已经成为SHIRO-298中的一个错误,并且已经在1.2.0-SNAPSHOT版本中解决了。您可以使用当前快照构建之一,也可以在发布时使用Shiro 1.2.0。
答案 1 :(得分:1)
看起来你的UI框架在注销后没有重新生成会话。 您可以尝试在登录调用之前强制调用subject.getSession()的新会话。像这样:
private void tryLogin(UsernamePasswordToken token) {
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
try {
subject.login(token);