当CSRF与Spring Security集成时,会话超时导致Spring MVC中的Access Denied

Yag*_*ola 9 spring spring-mvc spring-security csrf-protection

我在Spring MVC项目中使用Spring Security集成了CSRF令牌.使用CSRF令牌一切正常,令牌将从客户端发送到服务器端.

我已经改变了我的logout进程,使其成为POST发送CSRF令牌的方法,并且其工作正常.

发生会话超时时我遇到问题,需要将其重定向到弹出默认注销URL,但它会为我Access Denied提供该URL.

如何覆盖此行为.

我在安全配置文件中包含以下行

   <http>
         //Other config parameters
        <csrf/>
   </http>
Run Code Online (Sandbox Code Playgroud)

如果有人需要更多信息,请告诉我.

mdr*_*drg 13

问题有点旧,但答案总是有用的.

首先,这是会话支持的CSRF令牌的已知问题,如文档中所述:CSRF警告 - 超时.

要解决此问题,请使用一些Javascript来检测即将发生的超时,使用与会话无关的CSRF令牌存储库或创建自定义AccessDeniedHandler路由.我选择后者:

配置XML:

<http>
    <!-- ... -->
    <access-denied-handler ref="myAccessDeniedHandler"/>
</http>

<bean id="myAccessDeniedHandler" class="package.MyAccessDeniedHandler">
    <!-- <constructor-arg ref="myInvalidSessionStrategy" /> -->
</bean>
Run Code Online (Sandbox Code Playgroud)

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. */
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以将自定义处理程序定义为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>
Run Code Online (Sandbox Code Playgroud)