Spring Security CSRF过滤器与登录页面上的会话管理冲突

时间:2016-01-11 18:39:06

标签: spring spring-security csrf

我正在调整项目以使用Spring Security CSRF保护,而且我得到了一个有趣的行为。在我的登录页面上,如果我刷新页面一次,三次,五次等等,那么当我在其中放入适当的凭据时,由于CSRF失败而将我踢出去,但是如果我立即登录或者在两次,四次,六次等之后登录刷新,我接受了。

我在为什么会这样做方面取得了进展,但我无法弄清楚如何解决这个问题。似乎每个其他请求只生成一个新的CSRF令牌,即使每次请求都以新会话结束。潜入Spring逻辑表明,最有可能发生以下事件序列:

  1. 我点击第一个请求的页面。 CSRF过滤器创建排序SaveOnAccessCsrfToken的标记(T1),并将其添加为请求属性。
  2. 创建新会话(S1)。
  3. JSP呈现,导致请求中的令牌(T1)被调用,SaveOnAccessCsrfToken将令牌保存到会话中(S1)。
  4. 我再次点击该页面。 CSRF过滤器仍然会看到旧会话(S1),因此从会话中获取DefaultCsrfToken并将此(旧令牌 - T1)添加到请求中,而不是创建新请求。
  5. 创建新会话(S2)。
  6. JSP呈现,导致请求中的令牌(T1)被调用,但由于它是DefaultCsrfToken,因此没有任何内容添加到会话中(S2)。
  7. 我再次点击该页面。 CSRF过滤器仍然看到旧会话(S2),但由于没有添加任何内容,因此它会创建排序SaveOnAccessCsrfToken的新令牌(T2),并将其添加为请求属性。
  8. 创建新会话(S3)。
  9. JSP呈现,导致请求中的令牌(T2)被调用,SaveOnAccessCsrfToken将令牌保存到会话中(S3)。
  10. 我再次点击该页面。我相信你现在看到这是如何重复的。
  11. 我似乎解决方案是在会话创建时更改,但我无法弄清楚如何做到这一点。想法?

    使用Spring 4.2.2和Spring-Security 4.0.3

    这是安全性XML:

    <?xml version="1.0" encoding="UTF-8"?> 
    <beans:beans xmlns="http://www.springframework.org/schema/security"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xmlns:beans="http://www.springframework.org/schema/beans"
                 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
    <http pattern="/resources/**" security="none" />        
    <http pattern="/WEB-INF/**" security="none" />
    <http pattern="/error/**" security="none" />
    <!-- Other unrelated URLs -->
    
    <!-- Configure Spring URL based Web Security  -->
    <http>
        <intercept-url pattern="/login**" access="permitAll"/>
        <!-- Other unrelated URLs -->
    
        <intercept-url pattern="/**" access="isFullyAuthenticated()"/> 
    
        <form-login login-page="/login" 
                    authentication-failure-url="/loginFailure?$general{login.fail.urlPostFix}" 
                    default-target-url="/afterSuccessfulLogin"
                    login-processing-url="/j_spring_security_check" /> 
    
        <logout delete-cookies="JSESSIONID"
                invalidate-session="false" 
                logout-success-url="/login" 
                logout-url="/logout" /> 
    
        <session-management invalid-session-url="/login?invalidSession=true" />
        <access-denied-handler error-page="/denied" />
        <headers disabled="true" />
    </http> 
    
    <authentication-manager> 
        <authentication-provider user-service-ref="adminSecurityService"> 
            <password-encoder ref="passwordEncoder"/>
        </authentication-provider> 
    </authentication-manager>
    
    <!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
    <beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder" />
    

0 个答案:

没有答案