Spring security Spring security csrf不适用于Spring会话

Spring security Spring security csrf不适用于Spring会话,spring-security,spring-session,Spring Security,Spring Session,我使用的是spring会话版本1.0.0.M1,我已将其配置为使用MapSessionRepository: sessionFilterChainReg.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),false,dispatcherServletReg.getName()) 然后在web配置中: final FilterRegistration sessionFilterChainReg = servletCon

我使用的是spring会话版本1.0.0.M1,我已将其配置为使用
MapSessionRepository
: sessionFilterChainReg.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),false,dispatcherServletReg.getName())

然后在web配置中:

    final FilterRegistration sessionFilterChainReg = servletContext.addFilter("sessionFilter", DelegatingFilterProxy.class);
因此,我在register.jsp中有以下输入隐藏元素:

<input type="hidden" id="${_csrf.parameterName}" name="${_csrf.parameterName}" value="${_csrf.token}"/>
现在会话为null,因此存储库返回null CSRF令牌,然后抛出
MissingCsrfTokenException
。是否还有其他需要配置的内容

这是当点击第66行时的stacktrace(还有很多,但我想这是它的相关部分):


发现问题-我自己有一个
过滤器
,它包装了
HttpServletRequest
对象,并且过滤器在
SessionRepositoryFilter
之前启动。我不确定这是否正确,但要在
SessionRepositoryFilter
之后强制启动它,我执行了以下操作:

@Bean(name = {"defaultSessionFilter", "sessionFilter"})
public Filter sessionFilter() {
    CompositeFilter compositeFilter = new CompositeFilter();
    compositeFilter.setFilters(Arrays.asList(new SessionRepositoryFilter((SessionRepository) applicationContext.getBean("sessionRepository")), applicationContext.getBean("myFilter")));

    return compositeFilter;
}

这就解决了问题。

CSRF支持在准备包含CSRF令牌的视图之前不会创建会话。您在哪里使用CSRF令牌?您需要一个包含CSRF令牌的视图(即JSP、Thymeleaf模板、响应头等)。另一件要尝试的事情是,它在春季课程中有效吗?嗨,罗布,我更新了这个问题。是的,它在没有spring会话的情况下工作得很好,并且CSRF令牌被正确地传递到筛选器,但是在HttpSessionSrftokenRepository:loadToken:66上返回的会话为空。您可以查看请求以查看存在哪些cookie吗?这可能与如果您看到多个会话cookie有关,您应该删除所有会话cookie,然后重试。嗨,Rob,我有很多cookie(大约35个),其中只有一个被调用的会话。我删除了所有cookies并重试,但结果是一样的-我得到MissingCsrfTokenException。另外,我刚刚注意到,不仅注册表单不起作用,而且登录表单现在也被破坏了——完全相同的问题。当您将调试点添加到HttpSessionSrftokenRepository:loadToken:66时,是否可以从IDE将调用堆栈复制/粘贴到post?
HttpSession session = request.getSession(false);
at org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.loadToken(HttpSessionCsrfTokenRepository.java:66)
  at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:75)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:144)
  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
  at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1632)
  at org.springframework.session.web.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:83)
  at org.springframework.session.web.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:66)
  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
  at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1632)
@Bean(name = {"defaultSessionFilter", "sessionFilter"})
public Filter sessionFilter() {
    CompositeFilter compositeFilter = new CompositeFilter();
    compositeFilter.setFilters(Arrays.asList(new SessionRepositoryFilter((SessionRepository) applicationContext.getBean("sessionRepository")), applicationContext.getBean("myFilter")));

    return compositeFilter;
}