当前位置: 首页 > 知识库问答 >
问题:

在Spring Boot中禁用特定URL模式的CSRF保护

谭彦
2023-03-14

我使用Spring Boot和Spring Security创建我的web项目。我想禁用特定URL模式的CSRF保护,为Android设备提供API。

使用

  • 如何通过XML配置和
  • Spring Boot的第一种方法:仅对某些请求选择性地启用CSRF检查

我写了以下配置:

package com.hnu.tutorial.configs;

import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CsrfSecurityRequestMatcher crm = new CsrfSecurityRequestMatcher();
        http.csrf().requireCsrfProtectionMatcher(crm).and()
                .authorizeRequests().antMatchers("/**").permitAll().anyRequest().fullyAuthenticated();
//        http.csrf().disable();
    }

    public class CsrfSecurityRequestMatcher implements RequestMatcher {
        private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
        private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("/api/**", null);

        @Override
        public boolean matches(HttpServletRequest request) {
            if(allowedMethods.matcher(request.getMethod()).matches()){
                return false;
            }
            return !unprotectedMatcher.matches(request);
        }
    }

}

运行此项目时,我会出现以下错误:

2016-08-08 09:29:27.172 ERROR 6715 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Exception starting filter springSecurityFilterChain

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 6
/api/**
      ^
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:199) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) ~[tomcat-embed-core-8.0.33.jar:8.0.33]
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109) ~[tomcat-embed-core-8.0.33.jar:8.0.33]
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4658) [tomcat-embed-core-8.0.33.jar:8.0.33]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5277) [tomcat-embed-core-8.0.33.jar:8.0.33]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [tomcat-embed-core-8.0.33.jar:8.0.33]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.33.jar:8.0.33]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.33.jar:8.0.33]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_73]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_73]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_73]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_73]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 6
/api/**
      ^
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    ... 23 common frames omitted
Caused by: java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 6
/api/**
      ^
    at java.util.regex.Pattern.error(Pattern.java:1955) ~[na:1.8.0_73]
    at java.util.regex.Pattern.sequence(Pattern.java:2123) ~[na:1.8.0_73]
    at java.util.regex.Pattern.expr(Pattern.java:1996) ~[na:1.8.0_73]
    at java.util.regex.Pattern.compile(Pattern.java:1696) ~[na:1.8.0_73]
    at java.util.regex.Pattern.<init>(Pattern.java:1351) ~[na:1.8.0_73]
    at java.util.regex.Pattern.compile(Pattern.java:1028) ~[na:1.8.0_73]
    at org.springframework.security.web.util.matcher.RegexRequestMatcher.<init>(RegexRequestMatcher.java:68) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.web.util.matcher.RegexRequestMatcher.<init>(RegexRequestMatcher.java:52) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at com.hnu.tutorial.configs.SecurityConfig$CsrfSecurityRequestMatcher.<init>(SecurityConfig.java:35) ~[classes/:na]
    at com.hnu.tutorial.configs.SecurityConfig.configure(SecurityConfig.java:27) ~[classes/:na]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:199) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:290) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:67) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at com.hnu.tutorial.configs.SecurityConfig$$EnhancerBySpringCGLIB$$db9c0de0.init(<generated>) ~[classes/:na]
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:370) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:324) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$5dd0484b.CGLIB$springSecurityFilterChain$4(<generated>) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$5dd0484b$$FastClassBySpringCGLIB$$a796ba38.invoke(<generated>) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$5dd0484b.springSecurityFilterChain(<generated>) ~[spring-security-config-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    ... 24 common frames omitted

上面的日志显示正则表达式/api/**

private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("/api/**", null);

在索引6/api/**附近有悬挂的元字符“*”。但我不知道这个错误意味着什么。

共有3个答案

龚伯寅
2023-03-14

虽然我不知道如何使用RegexRequestMatcher匹配未受保护的url模式,但我找到了另一种解决方案。以下内容对我来说很好:

@Override
    protected void configure(HttpSecurity http) throws Exception {

        RequestMatcher csrfRequestMatcher = new RequestMatcher() {

            // Enabled CSFR protection on the following urls:
            private AntPathRequestMatcher[] disableCsrfMatchers = {
                    new AntPathRequestMatcher("/api/**")
            };

            @Override
            public boolean matches(HttpServletRequest request) {
                // If the request match one url the CSFR protection will not be enabled
                for (AntPathRequestMatcher rm : disableCsrfMatchers) {
                    if (rm.matches(request)) {
                        return false;
                    }
                }
                return true;
            } // method matches

        };

        http.csrf().requireCsrfProtectionMatcher(csrfRequestMatcher).and()
                .authorizeRequests().antMatchers("/**").permitAll().anyRequest().fullyAuthenticated();
    }
何兴学
2023-03-14

尝试以下操作以允许api调用绕过CSRF检查。

final String API_URL = "/api/*";
http.csrf()
    .requireCsrfProtectionMatcher(new RequestMatcher() {
        private RegexRequestMatcher requestMatcher = new RegexRequestMatcher(API_URL, null);

        @Override
        public boolean matches(HttpServletRequest request) {
            return !requestMatcher.matches(request);
        }
    })
    .csrfTokenRepository(csrfTokenRepository());
刁跃
2023-03-14

对于那些对如何禁用特定路径的CSRF验证有疑问的人,我发现最简单的方法是创建一个带有模式的字符串数组,如下所示:

String [] publicUrls = new String [] {
            "/public/**",
            "/login",
            "/logout"
    };

以下是我在CSRF中使用的代码。忽略URL的代码是这样的。ignoringAntMatchers(publicURL)

.csrf()
        .csrfTokenRepository(csrfTokenRepository())
        .ignoringAntMatchers(publicUrls)

我在这里找到这个。

 类似资料:
  • Csrf筛选器验证从“验证”提交的Csrf令牌,当我从HTTP向https提交请求时,抛出无效令牌异常(403)。如何在这种情况下禁用csrf令牌身份验证?

  • 如何在Spring Security 4中通过XML配置仅对特定URL模式禁用CSRF? Spring安全。xml 我的代码工作正常,如果我只使用一个安全:http块,但在我添加另一个块后,它抛出错误如下: 错误

  • 使用CSRF保护,这样从其他网站发出的任何请求都不会影响我的网站造成伤害。在Spring安全csrf留档中说,csrf应用于放帖补丁删除请求。 但据我了解,登录/注册表单不需要csrf保护,因为它们已经需要用户名和密码形式的凭据,即使是从另一个网站发出这样的请求,也不会有任何伤害,因为用户只需登录即可。 但是由于登录通常是一个发布请求,csrf将在Spring默认情况下自动应用。这意味着我需要将c

  • 问题内容: 我正在使用无状态Spring Security,但是如果要注册,我想禁用Spring Security。我禁用了 但它不起作用,我在下面收到错误消息: 我认为这意味着弹簧安全过滤器正在工作 我的网址顺序始终为“ / api / v1” 我的spring配置是 我的身份验证过滤器是 我的控制器是 我怎么做? 问题答案: 使用它意味着每个经过身份验证的用户,但是你禁用了匿名访问,因此将无法

  • 我的: 编辑:我的: 我还尝试添加。 任何帮助都很感激。谢了! ...是的,我已经在配置更改后重新启动了守护进程。:)

  • 我的Spring Boot REST API受KeyClope实例的保护。由于CSRF保护只允许GET和POST,我想禁用它。然而,我的方法似乎不起作用,因为REST API将为任何来源不同于的请求返回HTTP状态403http://localhost:8080.以下是我如何配置我的安全性: 带有http://localhost:8080起源的请求将起作用: 编辑: 这就是我的CustomCors