我有一个基于Spring Security和Spring MVC的Spring 4 Web应用程序。它包括CSRF保护,以及记住我功能。此后包括配置的相关部分。
<sec:http auto-config="true">
<sec:intercept-url pattern="/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<sec:intercept-url pattern="/**" access="ROLE_USER" />
<sec:access-denied-handler error-page="/403" />
<sec:form-login
login-page="/public/login"
authentication-failure-url="/public/login?error"
authentication-success-handler-ref="authenticationSuccessHandler"
username-parameter="userName"
password-parameter="password" />
<sec:logout
logout-url="/logout"
logout-success-url="/public/login?logout"
delete-cookies="JSESSIONID" />
<sec:remember-me
services-ref="rememberMeServices" key="***" />
<sec:csrf />
</sec:http>
<bean id="securityService" class="custom UserDetailsService" />
<bean id="authenticationSuccessListener" class="custom ApplicationListener" />
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<property name="key" value="***" />
<property name="userDetailsService" ref="securityService" />
<property name="tokenRepository" ref="custom PersistentTokenRepository" />
<property name="parameter" value="rememberMe" />
</bean>
<bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="targetUrlParameter" value="targetUrl" />
</bean>
场景:用户打开POST表单并开始填写,接听电话或其他任何内容,会话超时,CSRF令牌无效,用户提交表单,并获得“拒绝访问”。我一直在浏览器中手动删除JSESSIONID cookie来测试这种情况(保留SPRING_SECURITY_REMEMBER_ME_COOKIE)。
期望:当会话超时时,记住我,开始验证用户,并成功处理请求。
问题:鉴于CSRF的性质和记住我,我的期望是合理的,还是从根本上有缺陷?推出我自己的CsrfTokenRepository实现,将令牌存储在数据库而不是会话中是否有意义?上述情景的普遍接受的方法是什么?
提前致谢。
答案 0 :(得分:0)
您需要警告用户会话即将过期。
如果您的系统支持实体的草稿版本,则可以在会话超时之前自动保存草稿。
然后显示一个对话框,指示会话已超时,并且他们需要再次登录,或者至少单击刷新。为了获得良好的安全性,您应该将它们重定向到登录页面。
<script>
/* where n is the number of seconds until session times out on server */
window.setTimeout(function(){
autoSaveCurrentForm();
showWarning();
}, n);
</script>