退出的基本配置:
<logout logout-url="/logout.htm" logout-success-url="/login.htm" invalidate-session="true" />
也可以自定义退出成功的handler,添加配置success-handler-ref。如果不配置logout-url,默认的退出url是j_spring_security_logout。处理退出时Spring Security3将会做的事:
- 使得HTTP session失效(如果invalidate-session属性被设置为true,默认是true的);
- 清除SecurityContex(真正使得用户退出);
- 将页面重定向至logout-success-url指明的URL。
- 如果启用了rememberme,清除cookie
退出过滤器是:org.springframework.security.web.authentication.logout.LogoutFilter,退出的流程比较简单:
看源码:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (requiresLogout(request, response)) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (logger.isDebugEnabled()) {
logger.debug("Logging out user '" + auth + "' and transferring to logout destination");
}
// 循环调用退出handler,执行logout方法
for (LogoutHandler handler : handlers) {
handler.logout(request, response, auth);
}
// 退出成功后的handler
logoutSuccessHandler.onLogoutSuccess(request, response, auth);
return;
}
chain.doFilter(request, response);
}
handlers集合默认在org.springframework.security.config.http.LogoutBeanDefinitionParser配置的:
ManagedList handlers = new ManagedList();
SecurityContextLogoutHandler sclh = new SecurityContextLogoutHandler();
if ("true".equals(invalidateSession)) {
sclh.setInvalidateHttpSession(true);
} else {
sclh.setInvalidateHttpSession(false);
}
//一个SecurityContextLogoutHandler对象
handlers.add(sclh);
// 如果启用了rememberme,还需要清理cookie
if (rememberMeServices != null) {
handlers.add(new RuntimeBeanReference(rememberMeServices));
}
builder.addConstructorArgValue(handlers);
先看SecurityContextLogoutHandler的logout方法
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
Assert.notNull(request, "HttpServletRequest required");
// 销毁session
if (invalidateHttpSession) {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
}
// 设置SecurityContextHolder对象为空
SecurityContextHolder.clearContext();
}
启用rememberme时,退出清除了cookie:AbstractRememberMeServices
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
if (logger.isDebugEnabled()) {
logger.debug( "Logout of user "
+ (authentication == null ? "Unknown" : authentication.getName()));
}
//清除cookie
cancelCookie(request, response);
}
退出成功后将根据配置重定向到一个url。