我在Spring MVC项目中使用Spring Security集成了CSRF令牌.使用CSRF令牌一切正常,令牌将从客户端发送到服务器端.
我已经改变了我的logout
进程,使其成为POST
发送CSRF令牌的方法,并且其工作正常.
发生会话超时时我遇到问题,需要将其重定向到弹出默认注销URL,但它会为我Access Denied
提供该URL.
如何覆盖此行为.
我在安全配置文件中包含以下行
//Other config parameters
如果有人需要更多信息,请告诉我.
问题有点旧,但答案总是有用的.
首先,这是会话支持的CSRF令牌的已知问题,如文档中所述:CSRF警告 - 超时.
要解决此问题,请使用一些Javascript来检测即将发生的超时,使用与会话无关的CSRF令牌存储库或创建自定义AccessDeniedHandler
路由.我选择后者:
配置XML:
<http> <!-- ... --> <access-denied-handler ref="myAccessDeniedHandler"/> </http> <bean id="myAccessDeniedHandler" class="package.MyAccessDeniedHandler"> <!-- <constructor-arg ref="myInvalidSessionStrategy" /> --> </bean>
MyAccessDeniedHandler:
public class MyAccessDeniedHandler implements AccessDeniedHandler { /* ... */ @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception) throws IOException, ServletException { if (exception instanceof MissingCsrfTokenException) { /* Handle as a session timeout (redirect, etc). Even better if you inject the InvalidSessionStrategy used by your SessionManagementFilter, like this: invalidSessionStrategy.onInvalidSessionDetected(request, response); */ } else { /* Redirect to a error page, send HTTP 403, etc. */ } } }
或者,您可以将自定义处理程序定义为DelegatingAccessDeniedHandler
:
<bean id="myAccessDeniedHandler" class="org.springframework.security.web.access.DelegatingAccessDeniedHandler"> <constructor-arg name="handlers"> <map> <entry key="org.springframework.security.web.csrf.MissingCsrfTokenException"> <bean class="org.springframework.security.web.session.InvalidSessionAccessDeniedHandler"> <constructor-arg name="invalidSessionStrategy" ref="myInvalidSessionStrategy" /> </bean> </entry> </map> </constructor-arg> <constructor-arg name="defaultHandler"> <bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl"> <property name="errorPage" value="/my_error_page"/> </bean> </constructor-arg> </bean>