如何手动注销弹簧安全的用户?
可能答案很简单:如何在春季安全中手动注销当前login的用户? 打电话是否足够?
SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false);
?
在Servlet 3.0容器中,Spring注销function与servlet集成在一起,您只需在HttpServletRequest
上调用logout()
。 仍然需要编写有效的响应内容。
根据文档 (Spring 3.2):
HttpServletRequest.logout()方法可以用来logging当前用户。
通常这意味着SecurityContextHolder将被清除,HttpSession将失效,任何“记住我”身份validation将被清除,等等。
我很难确定你的代码是否足够。 但是标准的Spring-security的注销实现是不同的。 如果你看看SecurityContextLogoutHandler
你会看到它们:
SecurityContextHolder.clearContext();
而且,他们可以使HttpSession失效:
if (invalidateHttpSession) { HttpSession session = request.getSession(false); if (session != null) { session.invalidate(); } }
你可以在Spring Security中查看更多关于注销的其他问题的信息,并查看org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler
的源代码 。
我在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); }
要注销Web应用程序中的用户,您还可以将其redirect到注销页面。 LogoutFilter然后为你做所有的工作。
注销页面的URL在安全configuration中设置:
<sec:http ...> ... <sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" /> ... </sec:http>
您也可以使用SessionRegistry :
sessionRegistry.getSessionInformation(sessionId).expireNow();
如果要强制在用户的所有会话中注销,请使用getAllSessions
方法并调用每个会话信息的expireNow
。
编辑
这需要ConcurrentSessionFilter
(或链中的任何其他filter),它检查SessionInformation并调用所有注销处理程序,然后redirect。
最近我们不得不使用Spring-security 3.0.5来实现注销function。 虽然这个问题已经在上面回答了,但我会发布完整的代码,肯定会帮助像我这样的新手用户:)
在Spring-security.xml中configuration
<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"/>
在这里我创build了两个自定义类
- XXXLogoutHandler将实现org.springframework.security.web.authentication.logout.LogoutHandler并将覆盖logout()方法。
- XXXLogoutSuccessHandler将实现org.springframework.security.web.authentication.logout.LogoutSuccessHanlder并将重写onLoguoutSuccess()方法。 在XXXLogoutSuccessHandler.onLogoutSuccess()方法中,调用将用户注销到特定的targetURL的redirectStrategy.sendRedirect()方法。
- org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler执行使用户会话无效的任务。
希望这将有助于给正确的方向发起人
注意 :有意没有为自定义实现发布代码。
只要做这样的事情(那些评论“关注你”):
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 }
new SecurityContextLogoutHandler().logout(request, null, null);
正确的Oledzki,我在我的控制器内使用以下例如注销和redirect用户到春季安全4.2.3的login页面
SecurityContextHolder.clearContext(); if(session != null) session.invalidate(); return "redirect:/login";