3

我在 Web 应用程序中使用 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 注销会使会话无效,并且重新登录应该访问一个新会话。

4

2 回答 2

3

如果有人(或其他东西)在Subject.logout()调用之前(例如httpSession.invalidate(),然后subject.logout())使会话无效,这将在版本 1.2 之前的 Shiro 中发生。

这已作为SHIRO-298中的错误提出,并且已在 1.2.0-SNAPSHOT 版本中得到解决。您可以使用当前的快照版本之一,也可以在发布时使用 Shiro 1.2.0。

于 2012-01-17T19:14:23.437 回答
1

看起来您的 UI 框架在注销后没有重新生成会话。您可以尝试在登录调用之前强制一个新的会话调用 subject.getSession() 。像这样的东西:

private void tryLogin(UsernamePasswordToken token) {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        try {
              subject.login(token);
于 2012-01-17T15:27:10.223 回答