【发布时间】:2015-12-22 08:47:17
【问题描述】:
我真的很想了解 Spring Security 的工作原理,但我现在有点迷茫。这是一个简单的场景:
- 用户访问网站首页但未登录
-
SecurityContextPersistenceFilter记录没有可用的 SecurityContext 并将创建一个新的 -
AnonymousAuthenticationFilter使用匿名令牌填充 SecurityContextHolder - 创建了一个 ID = C2A35ED5A41E29865FF53162B0024D52 的会话
- 用户让页面处于空闲状态,直到会话超时
- 用户点击“关于”页面(或再次点击主页)
-
SecurityContextPersistenceFilter再次记录没有可用的 SecurityContext 并且将创建一个新的 -
AnonymousAuthenticationFilter再次使用匿名令牌填充 SecurityContextHolder -
SessionManagementFilter请求会话 ID C2A35ED5A41E29865FF53162B0024D52 的日志无效 -
SessionManagementFilter记录它正在启动一个新会话并重定向到 /invalidsession
这些页面配置为.authorizeRequests().antMatchers("/","/home","/about").permitAll(). 我打开了无效会话选项来处理经过身份验证的用户:.sessionManagement().invalidSessionUrl("/errors/invalidSession")。如果我注释掉该选项,那么上述所有内容都完全相同,除了步骤#10 - SessionManagementFilter 看到请求的会话 ID 无效(#9)但不会启动新会话并执行重定向(#10 )。
为什么?我可以做些什么来保留无效会话选项但正确处理匿名用户,即不被重定向?或者这是不可能的,我必须单独处理经过身份验证的用户?如果有人能帮助我了解这里发生的事情并为我指明解决这个问题的方向,我将不胜感激。如果您需要查看我的完整 http 配置,请告诉我。
编辑
我对匿名用户和注册(经过身份验证的)用户进行了一系列测试。如果启用.sessionManagement().invalidSessionUrl("/errors/invalidSession"),那么这两种类型的用户最终都会到达错误页面。未选中 RememberMe 的经过身份验证的用户与匿名用户相同。如果选中了 RememberMe,则在 RememberMe 超时后会出现错误页面。
如果我禁用无效会话选项,用户将永远不会看到错误页面(这是有道理的)。这两种类型的用户都可以根据需要浏览公共页面,并且在会话或 RememberMe 过期后,经过身份验证的用户将被要求登录。
如果您有兴趣,这里涉及的代码在SessionManagementFilter
if (invalidSessionStrategy != null) {
invalidSessionStrategy
.onInvalidSessionDetected(request, response);
return;
}
如果启用.sessionManagement().invalidSessionUrl,则调用默认方法SimpleRedirectInvalidSessionStrategy,它会执行这段代码:
if (createNewSession) {
request.getSession();
}
redirectStrategy.sendRedirect(request, response, destinationUrl);
createNewSession布尔值可以通过setCreateNewSession(boolean createNewSession)来设置,描述为:
确定是否应在重定向之前创建新会话(以避免在重定向请求中发送相同会话 ID 时可能出现的循环问题)。或者,确保配置的 URL 不通过
SessionManagementFilter。
所以,在我看来,.sessionManagement().invalidSessionUrl 最适合所有页面都经过身份验证的网站。我正在查看的选项是放置在SessionManagementFilter 之前的自定义过滤器,它检查页面访问并根据需要打开/关闭“createNewSession”,或者关闭无效会话选项并在其他地方处理经过身份验证的页面(?)。我还在这个 SO 问题中偶然发现了<%@ page session=“false” %> - Why set a JSP page session = “false” directive? - 我将进一步研究。作为 Spring Security 的新手,我对正确处理这种情况的最佳实践没有很好的认识。任何帮助将不胜感激。
【问题讨论】:
标签: spring-security