2011-04-20 57 views
56

可能的答案很简单:如何在春季安全中手动注销当前登录的用户? 是否足以拨打:如何手动注销弹簧安全的用户?

SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false); 

+0

非常感谢您的回答家伙,我会检查出来。 – Erik 2011-04-20 14:27:19

回答

27

在Servlet 3.0容器中Spring的注销功能与servlet集成在一起,您只需在HttpServletRequest上调用logout()即可。仍然需要编写有效的响应内容。

根据documentation(春季3.2):

的HttpServletRequest.logout()方法可用于出登录当前用户。

通常,这意味着SecurityContextHolder的将被清除出 ,在HttpSession将失效,任何 “记住我” 认证将被清理等

+0

具有的Tomcat 7的'org.apache.catalina.connector.Request对Spring 3.1.2/2.2.0的Grails#logout'实施的NPE。 'clearContext()'没有这样的错误。 – 2014-10-22 05:15:26

+0

@PavelVlasov我相信这是Spring配置中的一些错误,请阅读SecurityContextHolder。 – 2015-06-19 09:13:30

+1

后'request.logout()'我 'SecurityContextHolder.getContext()。getAuthentication仍然授权用户()' – GKislin 2017-10-25 15:08:40

56

我很难确定您的代码是否足够。然而标准的Spring-security的注销实现是不同的。如果您在SecurityContextLogoutHandler接过来一看,你会看到他们这样做:

SecurityContextHolder.clearContext(); 

此外,他们可选择无效的HttpSession:

if (invalidateHttpSession) { 
     HttpSession session = request.getSession(false); 
     if (session != null) { 
      session.invalidate(); 
     } 
    } 

您可能会发现更多的信息in some other question about logging out in Spring Security,并通过查看the source code of org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler。如果要强制注销的用户的所有会话,然后使用getAllSessions方法和调用每个会话的信息expireNow

sessionRegistry.getSessionInformation(sessionId).expireNow(); 

+2

您也想,如果它被设置为下降了rememberMe饼干。 – sourcedelica 2011-04-20 13:08:30

9

您还可以使用SessionRegistry作为。

编辑
这需要ConcurrentSessionFilter(或链中的任何其它过滤器),用来检查SessionInformation和调用所有注销处理程序,然后执行重定向。

10

要注销Web应用程序中的用户,您还可以将其重定向到注销页面。 LogoutFilter然后为你做所有的工作。

注销页面的URL设置在安全配置:

<sec:http ...> 
    ... 
    <sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" /> 
    ... 
</sec:http> 
+1

这没有为我工作。它并不像你所说的那么简单。有没有更多配置细节? – djangofan 2012-11-30 04:14:54

+0

应该有必要的任何其他配置这个工作。您只需将用户重定向到像“http://example.com/yourctx/logout”这样的URL即可。 – James 2012-11-30 07:55:20

+0

我得到它的工作,但我不得不重新启动Tomcat为它开始工作。 – djangofan 2012-11-30 17:33:22

15

我使用LogoutFilter相同的代码,重用LogoutHandlers如下:

public static void myLogoff(HttpServletRequest request, HttpServletResponse response) { 
    CookieClearingLogoutHandler cookieClearingLogoutHandler = new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY); 
    SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler(); 
    cookieClearingLogoutHandler.logout(request, response, null); 
    securityContextLogoutHandler.logout(request, response, null); 
} 
+0

+1,因为CookieClearingLogoutHandler,否则用户可以再次登录,如果她有了rememberme Cookie的话。请注意,这个类需要春天3.1 – redochka 2014-05-20 10:22:34

2

简单地做这样的(那些评论为“关注你”):

Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // concern you 

    User currUser = userService.getUserById(auth.getName()); // some of DAO or Service... 

    SecurityContextLogoutHandler ctxLogOut = new SecurityContextLogoutHandler(); // concern you 

    if(currUser == null){ 
     ctxLogOut.logout(request, response, auth); // concern you 
    } 
2

最近我们不得不实现注销f使用Spring-security 3.0.5的非功能性。尽管这个问题已经回答了上面,我将发布完整的代码,这肯定会帮助新手用户像我一样:)

配置在Spring-security.xml文件

<http auto-config="false" lowercase-comparisons="false" use-expressions="true"> 
    <custom-filter position="LOGOUT_FILTER" ref="logoutFilter" /> 
</http> 

<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> 
     <beans:constructor-arg name="logoutSuccessHandler" ref="xxxLogoutSuccessHandler" /> 
    <beans:constructor-arg name="handlers"> 
     <beans:list> 
      <beans:ref bean="securityContextLogoutHandler"/> 
      <beans:ref bean="xxxLogoutHandler"/> 
     </beans:list> 
    </beans:constructor-arg> 
    <beans:property name="filterProcessesUrl" value="/logout"/> 
</beans:bean> 
<beans:bean id="XXXLogoutSuccessHandler" class="com.tms.dis.sso.XXXLogoutSuccessHandler"/> 
<beans:bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"> 
    <beans:property name="invalidateHttpSession" value="true"/> 
</beans:bean> 
<beans:bean id="XXXLogoutHandler" class="com.tms.dis.sso.XXXLogoutHandler"/> 

在这里,我已经创建了两个自定义类

  1. XXXLogoutHandler它将实现org.springframework.security.web.authentication.logout.LogoutHandler并将覆盖logout()方法。
  2. XXXLogoutSuccessHandler它将实现org.springframework.security.web.authentication.logout.LogoutSuccessHanlder并将覆盖onLoguoutSuccess()方法。在XXXLogoutSuccessHandler.onLogoutSuccess()方法中,调用将用户注销到特定targetURL的redirectStrategy.sendRedirect()方法。
  3. org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler做用户会话失效的任务。

希望这会帮助,并给予正确的方向起动

注意:自定义实施故意没有公布代码。

1

new SecurityContextLogoutHandler().logout(request, null, null);

0

右Oledzki ,我使用例如下面我控制器内注销并将用户重定向到登录页面,在春季安全4.2.3

SecurityContextHolder.clearContext(); 

if(session != null) 
    session.invalidate(); 

return "redirect:/login";