Spring Security CSRF筛选器与登录页面上的会话管理冲突
我正在修改一个项目以使用SpringSecurityCSRF保护,我得到了一个有趣的行为。在我的登录页面上,如果我刷新页面一次、三次、五次,等等。然后,当我放入适当的凭据时,它会因为CSRF失败而将我踢出,但如果我立即登录或在两次、四次、六次等刷新后登录,我就可以正常登录 我已经在为什么会发生这种情况方面取得了进展,但我不知道如何解决这个问题。似乎只有在每次other请求时才会生成一个新的CSRF令牌,即使每次请求结束时我都会生成一个新会话。深入研究Spring逻辑发现,以下事件序列最有可能发生:Spring Security CSRF筛选器与登录页面上的会话管理冲突,spring,spring-security,csrf,Spring,Spring Security,Csrf,我正在修改一个项目以使用SpringSecurityCSRF保护,我得到了一个有趣的行为。在我的登录页面上,如果我刷新页面一次、三次、五次,等等。然后,当我放入适当的凭据时,它会因为CSRF失败而将我踢出,但如果我立即登录或在两次、四次、六次等刷新后登录,我就可以正常登录 我已经在为什么会发生这种情况方面取得了进展,但我不知道如何解决这个问题。似乎只有在每次other请求时才会生成一个新的CSRF令牌,即使每次请求结束时我都会生成一个新会话。深入研究Spring逻辑发现,以下事件序列最有可能发生
saveOnAccessSrftoken
将令牌保存到会话(S1)DefaultCsrfToken
,并将其(旧令牌-T1)添加到请求中,而不是创建新的会话DefaultCsrfToken
,因此不会向会话(S2)添加任何内容saveOnAccessSrftoken
将令牌保存到会话(S3)<?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" />
为什么还要创建一个新会话,您有自定义的登录表单还是使用默认的Spring安全表单?您使用的确切版本是什么?4.0.x(在本例中x是什么)。您还可以添加您的spring安全配置(或者您目前拥有的配置)。新会话创建在应用服务器上,我有一个自定义的登录表单。我在上面添加了其他信息。我知道会话是在哪里创建的,但为什么?已经有一个会话,应该呈现cookie,或者问题是,如果有会话,为什么它无效?假设您使用的是JSP,您可以将
添加到页面中,这样只有Spring Security创建会话,而不是JSP。创建会话是因为它是一个登录页面。人们通常不希望在登录页面上保留会话,因为这样一来,旧登录的参数就有流失到新登录的风险。添加session=false不仅没有修复它,而且还以新的令人兴奋的方式破坏了登录(这在这里似乎不相关)。您能够修复您的问题吗?你是怎么做到的?为什么还要创建一个新的会话,你有一个自定义的登录表单,还是使用默认的Spring安全表单?您使用的确切版本是什么?4.0.x(在本例中x是什么)。您还可以添加您的spring安全配置(或者您目前拥有的配置)。新会话创建在应用服务器上,我有一个自定义的登录表单。我在上面添加了其他信息。我知道会话是在哪里创建的,但为什么?已经有一个会话,应该呈现cookie,或者问题是,如果有会话,为什么它无效?假设您使用的是JSP,您可以将
添加到页面中,这样只有Spring Security创建会话,而不是JSP。创建会话是因为它是一个登录页面。人们通常不希望在登录页面上保留会话,因为这样一来,旧登录的参数就有流失到新登录的风险。添加session=false不仅没有修复它,而且还以新的令人兴奋的方式破坏了登录(这在这里似乎不相关)。您能够修复您的问题吗?你是怎么做到的?