Spring mvc 为什么不是';SpringSecurity是否将我的SecurityContext放入HttpSession?
我的公司内部网应用程序使用预验证方案。它在SpringSecurity过滤器链之前插入了两个过滤器。第一个是公司提供的过滤器。它处理所有登录、密码等,如果识别出用户,则将身份验证数据放入cookie中的主体中。第二个转换所有这些,创建UserDetails对象和身份验证令牌,并将其放置在SecurityContextHolder中Spring mvc 为什么不是';SpringSecurity是否将我的SecurityContext放入HttpSession?,spring-mvc,spring-security,pre-authentication,Spring Mvc,Spring Security,Pre Authentication,我的公司内部网应用程序使用预验证方案。它在SpringSecurity过滤器链之前插入了两个过滤器。第一个是公司提供的过滤器。它处理所有登录、密码等,如果识别出用户,则将身份验证数据放入cookie中的主体中。第二个转换所有这些,创建UserDetails对象和身份验证令牌,并将其放置在SecurityContextHolder中 SecurityContextHolder.getContext().setAuthentication(token); logger.debug("Auth tok
SecurityContextHolder.getContext().setAuthentication(token);
logger.debug("Auth token submitted");
我的日志确认正在发生这种情况:
2015-09-30 13:02:08,998 DEBUG c.a.v.c.s.MyPreauthFilter [http-bio-8081-exec-63] Auth token submitted
几毫秒后,Spring Security filter链进入并执行以下操作:
2015-09-30 13:02:09,002 DEBUG o.s.s.w.FilterChainProxy [http-bio-8081-exec-63] /index.html at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-09-30 13:02:09,007 DEBUG o.s.s.w.FilterChainProxy [http-bio-8081-exec-63] /index.html at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-09-30 13:02:09,008 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository [http-bio-8081-exec-63] HttpSession returned null object for SPRING_SECURITY_CONTEXT
2015-09-30 13:02:09,008 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository [http-bio-8081-exec-63] No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@721c23ce. A new one will be created.
基本上,httpsessionsecuritycontextextrespository
由SecurityContextPersistenceFilter
(过滤器链的一部分)调用,检查会话中的安全上下文,在会话中找不到,并用新的空上下文替换我刚刚放在SecurityContextHolder中的上下文,导致下面几行的身份验证失败
2015-09-30 13:02:09,024 DEBUG o.s.s.w.a.ExceptionTranslationFilter [http-bio-8081-exec-63] Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
由于Spring文档没有提到HttpSessionSecurityContextRespository,我想我可能不应该搞砸它
相反,我想也许我可以尝试在Spring安全过滤器链之后插入第二个过滤器,但这没有帮助。FilterSecurityInterceptor(链中的第11项)拒绝对我进行身份验证,就像我的第二个筛选器在链中的前面一样
在会话中保存SecurityContext的是什么?在清除刚刚设置的安全上下文时,如何克服SecurityContextPersistenceFilter的行为 我已经找到了一个解决办法。这本不必要,但似乎有效
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
...
PreAuthenticatedAuthenticationToken token = ...
logger.debug("Auth token placed in SecurityContext: \n" + token);
SecurityContextHolder.getContext().setAuthentication(token);
// make sure the session has a SecurityContext at this point
ensureSessionHasSecurityContext(hreq);
super.doFilter(request,response, chain);
logger.debug("Auth token after rest of chain: \n" + SecurityContextHolder.getContext()
.getAuthentication());
}
private void ensureSessionHasSecurityContext(HttpServletRequest hreq) {
HttpSession session = hreq.getSession(false);
Object securityContext = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
if (securityContext == null) {
logger.debug("no SecurityContext found in session, inserting ours");
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
}
}
如果您觉得这个解决方案有问题,请揭穿它。但这是我唯一能想到的确保过滤器链不会在我想要的时候,在我的预授权过滤器完成其工作之后,但在Spring过滤器链接管之前,破坏我的新身份验证的方法