用户在使用我自己的身份验证类(Spring MVC)进行注销后仍然登录

时间:2016-12-05 11:39:30

标签: java spring spring-mvc spring-security

我没有将用户信息放在Session中,而是扩展了Spring类User,创建了一个字段用户。

public class MyUser extends User {
   ...
}

然后我将Spring类UsernamePasswordAuthenticationToken扩展为“put”,在其中包含我的User类

 public class MyUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {                   
         private static final long serialVersionUID = -1353194962481509967L;        
         public MyUsernamePasswordAuthenticationToken(Object details, MyUser myUser, Object credentials, Collection<? extends GrantedAuthority> authorities) {            
                super(myUser, credentials, authorities);    
                super.setDetails(details);      
         }    
}

我还扩展了类SimpleUrlAuthenticationSuccessHandler,在用户成功登录后做了一些事情

    public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{

public void onAuthenticationSuccess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Authentication authentication) throws IOException, javax.servlet.ServletException {

      MyUsernamePasswordAuthenticationToken myUsernamePasswordAuthenticationToken = //here I do some stuff to create my myUsernamePasswordAuthenticationToken ;

        super.onAuthenticationSuccess(request, response, myUsernamePasswordAuthenticationToken);

        // I put myUsernamePasswordAuthenticationToken inside the Context
        SecurityContextHolder.getContext().setAuthentication(myUsernamePasswordAuthenticationToken );

            }

}

当然,我还扩展了Spring类SimpleUrlLogoutSuccessHandler

public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {

public void onLogoutSuccess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Authentication authentication) throws IOException, javax.servlet.ServletException{
        super.setDefaultTargetUrl("/pbl/login");
        super.onLogoutSuccess(request, response, authentication);

// in this method I tryed many types of cose, but I alwasy get the SessionAuthenticationException error.
//I don't show you all my old codes, since it didn't work and I don't want you to read other boring code.
}

}

除了ont之外,一切都有效。如果我从浏览器注销,然后尝试从其他浏览器登录,则会收到SessionAuthenticationException错误,告知我用户仍然登录。 如果我从broswer注销,然后尝试从同一个浏览器登录 ,我不会收到任何错误。

重要提示:在扩展课程UserUsernamePasswordAuthenticationToken等之前,我的SimpleUrlAuthenticationSuccessHandler工作正常,我没有收到任何SessionAuthenticationException错误。

sombody可以帮帮我吗?

提前谢谢。

修改

如果我添加

HttpSession session = (HttpSession)request.getSession();
session.invalidate();   

在方法onLogoutSuccess内部,一切似乎都正常,但我无法理解为什么。

解。

我在配置文件中制作了一个大型的桅杆:

<security:logout                    
    ...                                  
    invalidate-session="false" // false instead of true
    ... />

感谢大家的帮助。

2 个答案:

答案 0 :(得分:1)

据我所知,我认为您的logout功能无法正常运行。让我们来看看你提到的两个场景:

除了ont之外,一切都有效。如果我从浏览器注销然后我尝试从另一个浏览器登录,则会收到SessionAuthenticationException错误,该错误告诉我该用户仍然登录。

这种情况正在发生,因为您的注销不起作用且您之前的会话尚未被销毁,并且spring-security不允许用户同时拥有2个活动会话您允许并发登录您的应用程序添加了额外的支持。

因此,当您尝试从不同的浏览器登录时,spring-security会抛出用户已登录的异常。

如果我从浏览器退出,然后尝试从同一浏览器登录,我就不会收到任何错误。

在第二种情况下,因为您没有从系统注销。因此,当您从同一浏览器再次登录时,spring-security将使用您之前的会话并允许您输入应用程序。

通过使成功处理程序中的会话无效,您将强制销毁同时包含您的身份验证令牌的会话对象。因此,它实际上并不是退出网址,但是会话会使代码无效。

我希望,它会帮助您了解下面发生的事情。

答案 1 :(得分:0)

您使用

后尝试使用logoutRequestMatcher吗?

注销的HTTP请求

我认为你应该使用

  • .logout()
  • .logoutRequestMatcher(new AntPathRequestMatcher(&#34; / logout&#34;))

在您的安全配置中