Spring Security 3.2 CSRF 禁用特定 URL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22524470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:36:33  来源:igfitidea点击:

Spring Security 3.2 CSRF disable for specific URLs

springspring-mvcspring-security

提问by Mahesh

Enabled CSRF in my Spring MVC application using Spring security 3.2.

使用 Spring security 3.2 在我的 Spring MVC 应用程序中启用 CSRF。

My spring-security.xml

我的 spring-security.xml

<http>
 <intercept-url pattern="/**/verify"  requires-channel="https"/>
 <intercept-url pattern="/**/login*"  requires-channel="http"/>
 ...
 ...
 <csrf />
</http>

Trying to disable CSRF for requests that contain 'verify' in request URL.

尝试为请求 URL 中包含“验证”的请求禁用 CSRF。

MySecurityConfig.java

我的安全配置文件

@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

private CsrfMatcher csrfRequestMatcher = new CsrfMatcher();

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

    http.csrf().requireCsrfProtectionMatcher(csrfRequestMatcher);

}

class CsrfMatcher implements RequestMatcher {
    @Override
    public boolean matches(HttpServletRequest request) {

        if (request.getRequestURL().indexOf("verify") != -1)
            return false;
        else if (request.getRequestURL().indexOf("homePage") != -1)         
            return false;

        return true;
    }
}

}

Csrf filter validates CSRF token that is submitted from 'verify' and Invalid token exception (403) is thrown as I'm submitting request to https from http. How can I disable csrf token authentication in such a scenario ?

Csrf 过滤器验证从“验证”提交的 CSRF 令牌,并在我从 http 向 https 提交请求时抛出无效令牌异常 (403)。在这种情况下如何禁用 csrf 令牌身份验证?

回答by le0diaz

I know this is not a direct answer, but people (as me) usually don't specify spring's version when searching for this kinds of questions. So, since spring security a method existsthat lets ignore some routes:

我知道这不是一个直接的答案,但是人们(像我一样)在搜索此类问题时通常不会指定 spring 的版本。因此,由于 spring security存在一种可以忽略某些路由的方法:

The following will ensure CSRF protection ignores:

以下将确保 CSRF 保护忽略:

  1. Any GET, HEAD, TRACE, OPTIONS (this is the default)
  2. We also explicitly state to ignore any request that starts with "/sockjs/"
  1. 任何 GET、HEAD、TRACE、OPTIONS(这是默认值)
  2. 我们还明确声明忽略任何以“/sockjs/”开头的请求
     http
         .csrf()
             .ignoringAntMatchers("/sockjs/**")
             .and()
         ...

回答by Andrea

I hope that my answer can help someone else. I found this question searching for How to disable CSFR for specfic URLs in Spring Boot.

我希望我的回答可以帮助别人。我发现这个问题正在搜索How to disable CSFR for specific URLs in Spring Boot

I used the solution described here: http://blog.netgloo.com/2014/09/28/spring-boot-enable-the-csrf-check-selectively-only-for-some-requests/

我使用了这里描述的解决方案:http: //blog.netgloo.com/2014/09/28/spring-boot-enable-the-csrf-check-selectively-only-for-some-requests/

This is the Spring Security configuration that allow me to disable the CSFR control on some URLs:

这是 Spring Security 配置,它允许我禁用某些 URL 上的 CSFR 控件:

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

    // Build the request matcher for CSFR protection
    RequestMatcher csrfRequestMatcher = new RequestMatcher() {

      // Disable CSFR protection on the following urls:
      private AntPathRequestMatcher[] requestMatchers = {
          new AntPathRequestMatcher("/login"),
          new AntPathRequestMatcher("/logout"),
          new AntPathRequestMatcher("/verify/**")
      };

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

    }; // new RequestMatcher

    // Set security configurations
    http
      // Disable the csrf protection on some request matches
      .csrf()
        .requireCsrfProtectionMatcher(csrfRequestMatcher)
        .and()
      // Other configurations for the http object
      // ...

    return;
  } // method configure


  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) 
      throws Exception {

    // Authentication manager configuration  
    // ...

  }

}

It works with Spring Boot 1.2.2 (and Spring Security 3.2.6).

它适用于 Spring Boot 1.2.2(和 Spring Security 3.2.6)。

回答by George Siggouroglou

I am using Spring Security v4.1. After a lot of reading and testing, I disable the CSRF security feature for specific URLs using XML configuration.

我正在使用 Spring Security v4.1。经过大量阅读和测试,我使用 XML 配置禁用特定 URL 的 CSRF 安全功能。

<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:util="http://www.springframework.org/schema/util"
             xsi:schemaLocation="
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <http pattern="/files/**" security="none" create-session="stateless"/>

    <http>
        <intercept-url pattern="/admin/**" access="hasAuthority('GenericUser')" />
        <intercept-url pattern="/**" access="permitAll" />
        <form-login 
            login-page="/login" 
            login-processing-url="/login"
            authentication-failure-url="/login"
            default-target-url="/admin/"
            password-parameter="password"
            username-parameter="username"
        />
        <logout delete-cookies="JSESSIONID" logout-success-url="/login" logout-url="/admin/logout" />
        <http-basic />
        <csrf request-matcher-ref="csrfMatcher"/>
    </http>

    <beans:bean id="csrfMatcher" class="org.springframework.security.web.util.matcher.OrRequestMatcher">
        <beans:constructor-arg>
            <util:list value-type="org.springframework.security.web.util.matcher.RequestMatcher">
                <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                    <beans:constructor-arg name="pattern" value="/rest/**"/>
                    <beans:constructor-arg name="httpMethod" value="POST"/>
                </beans:bean>
                <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                    <beans:constructor-arg name="pattern" value="/rest/**"/>
                    <beans:constructor-arg name="httpMethod" value="PUT"/>
                </beans:bean>
                <beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
                    <beans:constructor-arg name="pattern" value="/rest/**"/>
                    <beans:constructor-arg name="httpMethod" value="DELETE"/>
                </beans:bean>
            </util:list>
        </beans:constructor-arg>
    </beans:bean>

    //...

</beans:bean>

With the above configuration, I enable the CSRF security onlyfor POST|PUT|DELETE requests of all URLs which start with /rest/.

通过上面的配置,我为所有以 开头的 URL 的 POST|PUT|DELETE 请求启用 CSRF 安全性/rest/

回答by blueDexter

Explicitly disable for specific url patterns and enable for some url patterns.

明确禁用特定 url 模式并启用某些 url 模式。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig {

    @Configuration
    @Order
    public static class GeneralWebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private CustomUserDetailsService userDetailsService;

        @Autowired
        private CustomPasswordEncoder passwordEncoder;

        @Autowired
        public void configureGlobalSecurity(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
            authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
        }

        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().ignoringAntMatchers("/rest/**").and()
            .authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/home/**","/search/**","/geo/**").authenticated().and().csrf()
            .and().formLogin().loginPage("/login")
            .usernameParameter("username").passwordParameter("password")
            .and().exceptionHandling().accessDeniedPage("/error")
            .and().sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
        }
    }
}

回答by zygimantus

Temporarily this simple line could be handy:

暂时这个简单的行可能很方便:

<http pattern="/home/test**" security="none" />

回答by user8462556

Use security="none". for e.g in spring-security-config.xml

使用安全=“无”。例如在 spring-security-config.xml 中

<security:intercept-url pattern="/*/verify" security="none" />