SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false);
?
SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false);
?
我很难确定你的代码是否足够。然而,标准的Spring Security登出实现是不同的。如果你查看SecurityContextLogoutHandler
,你会发现他们做了以下操作:
SecurityContextHolder.clearContext();
if (invalidateHttpSession) {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
}
您可以通过查看Spring Security中有关注销的其他问题在某些其他有关Spring Security注销的问题中以及查看org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler
的源代码来获取更多信息。
在Servlet 3.0容器中,Spring注销功能与servlet集成,您只需在HttpServletRequest
上调用logout()
即可。仍需要编写有效的响应内容。
根据文档 (Spring 3.2):
可以使用HttpServletRequest.logout()方法来注销当前用户。
通常这意味着SecurityContextHolder将被清除,HttpSession将被无效,任何"记住我"身份验证将被清除等。
org.apache.catalina.connector.Request#logout
实现会导致NPE错误。使用clearContext()
不会出现这种错误。 - Pavel Vlasovrequest.logout()
后,我仍然可以在 SecurityContextHolder.getContext().getAuthentication()
中找到已授权的用户。 - Grigory Kislin我在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);
}
你也可以使用SessionRegistry:
sessionRegistry.getSessionInformation(sessionId).expireNow();
如果您想强制注销用户的所有会话,则使用 getAllSessions
方法并调用每个会话信息的 expireNow
方法。
编辑ConcurrentSessionFilter
(或链中的任何其他过滤器),它检查SessionInformation并调用所有注销处理程序,然后进行重定向。在Web应用程序中注销用户时,您也可以将用户重定向到注销页面。然后LogoutFilter会为您完成所有工作。
注销页面的URL在安全配置中设置:
<sec:http ...>
...
<sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" />
...
</sec:http>
Right Oledzki,我在我的控制器中使用以下代码示例来注销并重定向用户到Spring Security 4.2.3中的登录页面:
SecurityContextHolder.clearContext();
if(session != null)
session.invalidate();
return "redirect:/login";
new SecurityContextLogoutHandler().logout(request, null, null);
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
}
在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"/>
我创建了两个自定义类:
希望这能有所帮助并为初学者提供正确的方向。
注意:故意没有发布自定义实现的代码。
非常简单,要手动注销Spring Security,只需利用Servlet请求本身即可。 例如:如下所示:
@PostMapping("/manualLogout")
public String customLogut(Model models, HttpServletRequest request) throws ServletException
{
request.logout();
return "redirect:/";
}