Spring Security 3.2 CSRF disable for specific URLs
Asked Answered
S

7

54

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

My 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.

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 ?

Sibylsibylla answered 20/3, 2014 at 5:49 Comment(4)
Before we try and troubleshoot this, Why are you using the XML and the JavaConfig? This may cause you such issues as I'm not sure which configuration is taking precedence. You should choose one or the other.Dehumidifier
Used XML configuration to channel some of URLs to https and others to http. Added CSRF feature in XML but we ran into a problem (Invalid Token) when user submits a request from a page that is channeled on https. 1. User lands on a page (home) on http 2. Navigates to a page (verify) that is on https 3. Gets the Invalid Token exception when request is submitted from verify page. So trying to disable CSRF authentication on verify page.Sibylsibylla
You can use the java config http.requiresChannel() to enable channel security with Java Configuration. Do not use both XML and JavaConfig use one or the other. My guess is that your Security Java Configuraiton is not being picked up or overridden by the XML configurationDehumidifier
Here is a well-done blog about how to disable the CSRF-check for some URLs, using xml configuration: blogs.sourceallies.com/2014/04/… Unfortunately it does not seem to work with my version Spring Security 3.2.8.Gama
P
70

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 exists that lets ignore some routes:

The following will ensure CSRF protection ignores:

  1. Any GET, HEAD, TRACE, OPTIONS (this is the default)
  2. We also explicitly state to ignore any request that starts with "/sockjs/"
http
    .csrf()
        .ignoringAntMatchers("/sockjs/**")
        .and()
         ...
Perse answered 25/1, 2016 at 13:53 Comment(2)
Works still fine with Spring Boot 2.1.4 and Spring Security 5.1.5Longitude
Can verify with Spring Security 5.20 and Spring MVC 5.2.0Neumark
C
16

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.

I used the solution described here: 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:

@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).

Classicist answered 19/3, 2015 at 14:44 Comment(0)
D
13

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.

<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 only for POST|PUT|DELETE requests of all URLs which start with /rest/.

Dennison answered 29/5, 2016 at 20:1 Comment(0)
R
9

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

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 {
        
        
        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);
        }
    }
}
Reata answered 25/9, 2019 at 9:22 Comment(0)
S
2
<http ...>
    <csrf request-matcher-ref="csrfMatcher"/>

    <headers>
        <frame-options policy="SAMEORIGIN"/>
    </headers>

    ...
</http>

<b:bean id="csrfMatcher"
    class="AndRequestMatcher">
    <b:constructor-arg value="#{T(org.springframework.security.web.csrf.CsrfFilter).DEFAULT_CSRF_MATCHER}"/>
    <b:constructor-arg>
        <b:bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
          <b:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
            <b:constructor-arg value="/chat/**"/>
          </b:bean>
        </b:bean>
    </b:constructor-arg>
</b:bean>

mean of

 http
        .csrf()
            // ignore our stomp endpoints since they are protected using Stomp headers
            .ignoringAntMatchers("/chat/**")

example from : https://docs.spring.io/spring-security/site/docs/4.1.x/reference/htmlsingle/

Systemic answered 20/10, 2020 at 11:46 Comment(1)
you forgot to wrap a constructor between NegatedRequestMatcher and AntPathRequestMatcherConduplicate
E
1

With Spring Security 6, the csrf method that takes a Customizer parameter should be used.

Sample configuration:

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.csrf(csrf -> csrf.ignoringRequestMatchers("/somepath", "/other/**"));
    return http.build();
}
Evasion answered 28/12, 2023 at 2:19 Comment(0)
H
-3

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

<security:intercept-url pattern="/*/verify" security="none" />
Hexapartite answered 5/9, 2017 at 17:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.