根据帖子Spring Security: Redirect to invalid-session-url instead of logout-success-url on successful logout,当退出会话时,Spring Security会重定向到用户定义的invalid-session-url。
<session-management invalid-session-url="/invalidSession.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
但,如果设置了注销成功网址
<logout invalidate-session="true"
logout-success-url="/logoutSuccess.jsp"
logout-url="/logout" />
在重定向到logout-success网址后,Spring仍然会重定向到无效的会话URL。即使logoutSuccess url不安全,也会发生这种情况。即,
<intercept-url pattern="/logoutSuccess.jsp*" access="permitAll"/>
这是一个Spring bug吗?由于logout-success-url已设置且不安全,因此在达到注销成功URL后,似乎不应将用户重定向到无效的会话URL。
日志如下所示:
INFO: [DEBUG,SimpleUrlLogoutSuccessHandler] Using default Url: /logoutSuccess.jsp
INFO: [DEBUG,DefaultRedirectStrategy] Redirecting to '/Application/logoutSuccess.jsp'
INFO: [DEBUG,HttpSessionSecurityContextRepository] SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
INFO: [DEBUG,SecurityContextPersistenceFilter] SecurityContextHolder now cleared, as request processing completed
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 1 of 10 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 2 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
INFO: [DEBUG,HttpSessionSecurityContextRepository] No HttpSession currently exists
INFO: [DEBUG,HttpSessionSecurityContextRepository] No SecurityContext was available from the HttpSession: null. A new one will be created.
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 3 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 4 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
INFO: [DEBUG,AnonymousAuthenticationFilter] Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
INFO: [DEBUG,FilterChainProxy] /logoutSuccess.jsp at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter'
INFO: [DEBUG,SessionManagementFilter] Requested session ID a396530a530b344ff531ab657e32 is invalid.
INFO: [DEBUG,SimpleRedirectInvalidSessionStrategy] Starting new session (if required) and redirecting to '/invalidsession.jsp'
INFO: [DEBUG,HttpSessionEventPublisher] Publishing event: org.springframework.security.web.session.HttpSessionCreatedEvent[source=org.apache.catalina.session.StandardSessionFacade@564c4200]
INFO: [DEBUG,DefaultRedirectStrategy] Redirecting to '/Application/invalidsession.jsp'
答案 0 :(得分:6)
reference manual中解释了这一点。
总而言之,“无效会话”功能基于提交的会话cookie的有效性,因此如果您在注销后访问该站点(或更具体地说,安全过滤器链),并且您仍然拥有{{ 1}} cookie,你可能会触发这种不受欢迎的行为。
如本手册的相同部分所述,您可以尝试使用
JSESSIONID
在退出时删除cookie。
答案 1 :(得分:2)
您必须小心,有时一起使用invalidate-session='true'
和delete-cookies=JSESSIONID
以及用户可以拥有的有限数量的会话,可能会让您“超出此主体的最大会话数为1” ,即使在您注销后也尝试登录时出现错误。
建议您在使用Spring Security 3.1及更高版本时仅使用 Delete-cookies 删除必要的会话信息。
答案 2 :(得分:0)
按如下所示配置注销,以删除安全配置WebSecurityConfigurerAdapter类中的cookie。
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//set access to all pages including session time out page where session time out is set in the application.properties page
httpSecurity
.authorizeRequests().antMatchers("/","/products","/product/show/*","/session","/console/*","/h2-console/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
//delete cookies so it won't get forwarded to session out page
httpSecurity.logout().deleteCookies("auth_code", "JSESSIONID").invalidateHttpSession(true);
httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();
httpSecurity.sessionManagement().invalidSessionUrl("/session");
}
最后在会话到期转发页面中手动删除cookie
@RequestMapping("/session")
String session(HttpServletRequest request,HttpServletResponse response){
SecurityContextHolder.clearContext();
HttpSession session= request.getSession(false);
Cookie[] cookies = request.getCookies();
// Delete all the cookies
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
cookies[i].setValue(null);
cookies[i].setMaxAge(0);
response.addCookie(cookie);
}
}
SecurityContextHolder.clearContext();
if(session != null) {
session.invalidate();
}
return "session";
}