加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 当会话在Spring安全性中超时时,处理请求中找到的无效CSR

发布时间:2020-12-15 00:41:42 所属栏目:Java 来源:网络整理
导读:我正在使用 Spring MVC / Security 3.X.问题是,每当会话超时时,我在登录页面上获得403,其中Spring框架正在抛出“InvalidCsrfTokenException”: threw exception [org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token '7b
我正在使用 Spring MVC / Security 3.X.问题是,每当会话超时时,我在登录页面上获得403,其中Spring框架正在抛出“InvalidCsrfTokenException”:
threw exception [org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token '7b4aefe9-6685-4c70-adf1-0d633680523a' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.] with root cause
org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token '7b4aefe9-6685-4c70-adf1-0d633680523a' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:119)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

正如在Spring文档中提到的那样,CSRF timeout是一个应该处理的问题.处理此场景的一种方法是使用自定义AccessDeniedHandler拦截CSRF异常.就像是:

static class CustomAccessDeniedHandler extends AccessDeniedHandlerImpl{

    @Override
    public void handle(HttpServletRequest request,HttpServletResponse response,AccessDeniedException accessDeniedException)
            throws IOException,ServletException {
        if (accessDeniedException instanceof MissingCsrfTokenException
                || accessDeniedException instanceof InvalidCsrfTokenException) {

            //What goes in here???

        }

        super.handle(request,response,accessDeniedException);

    }
}

问题:无需刷新页面(这是糟糕的用户体验)或无休止的会话,处理这种情况的最佳方法是什么?感谢您的帮助.

解决方法

当会话在登录页面超时时,我发现处理无效CSRF令牌的最简单方法是以下之一:

>再次将请求重定向到登录页面vi CustomAccessDeniedHandler:

static class CustomAccessDeniedHandler extends AccessDeniedHandlerImpl{




    @Override
    public void handle(HttpServletRequest request,AccessDeniedException accessDeniedException)
    throws IOException,ServletException {
if (accessDeniedException instanceof MissingCsrfTokenException
        || accessDeniedException instanceof InvalidCsrfTokenException) {

    if(request.getRequestURI().contains("login")){
        response.sendRedirect(request.getContextPath()+"/login");                                        
    }
}

super.handle(request,accessDeniedException);



 }
}

>添加刷新标题为Neil McGuigan建议:

< meta http-equiv =“refresh”content =“${pageContext.session.maxInactiveInterval}”>

>此外,您必须为新的CustomAccessDeniedHandler创建一个bean并注册它.以下示例显示了Java配置.

在任何配置类中:

@Bean
public AccessDeniedHandler accessDeniedHandler() {
    return new CustomAccessDeniedHandler();
}

在您的安全配置中,修改configure方法,如下所示:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
      // ...
      .and()
      .exceptionHandling().accessDeniedHandler(accessDeniedHandler());
}

另见here.

一个更优化的解决方案将是Spring安全性在其框架中处理这种情况.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读