Webflux禁用特定URL上的CSRF

时间:2018-08-29 20:01:53

标签: spring spring-security spring-webflux

这个想法是在webflux中复制http://blog.netgloo.com/2014/09/28/spring-boot-enable-the-csrf-check-selectively-only-for-some-requests/

这是我到目前为止的去处:

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {

    @Bean
    SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http) {
        http
           .csrf().requireCsrfProtectionMatcher(
                  new ServerWebExchangeMatcher() {

                    @Override
                    public Mono<MatchResult> matches(ServerWebExchange serverWebExchange) {
                    // here check if the url should have csrf or not and then return MatchResult.match() or notMatch(), however I find that if I return match then I get 'Invalid CSRF Token' error.
                    //    return MatchResult.match();
                    //    return MatchResult.notMatch();
                    }
                }
                ).and()
                .anyExchange().authenticated()
                .and()
                .httpBasic()
                .and()
                .formLogin().loginPage("/login")
                .and().logout()

        return http.build();
    }
}

3 个答案:

答案 0 :(得分:3)

这应该做

    @Bean
    SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http) {
        http
           .csrf().requireCsrfProtectionMatcher(
                  new ServerWebExchangeMatcher() {

                    @Override
                    public Mono<MatchResult> matches(ServerWebExchange serverWebExchange) {
                        ServerWebExchangeMatchers.pathMatchers("/urls-with-csrf-check/**").matches(serverWebExchange)
                    }
                }
                ).and()
                .anyExchange().authenticated()
                .and()
                .httpBasic()
                .and()
                .formLogin().loginPage("/login")
                .and().logout()

        return http.build();
    }

答案 1 :(得分:0)

允许配置来源:

@Bean
public WebFluxConfigurer corsConfigurer() {
    return new WebFluxConfigurerComposite() {

        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry
                .addMapping("/**")
                .allowedOrigins("/goodss")
                .allowedMethods("*");
        }
    };
}

答案 2 :(得分:0)

我来晚了,但经过大量研究,我找到了一个很好的解决方案。

假设您想对特定 URL 禁用 CSRF 检查。就我而言,我想对匹配此模式 /token/** 的 URL 禁用 CSRF 检查。

因此,首先,您需要创建一个 NegatedServerWebExchangeMatcher 实例,您将在其中添加要禁用 CSRF 检查的所有 URL 模式。就我而言,我将创建一个只为 NegatedServerWebExchangeMatcher 模式返回 /token/** 的方法。 所以,这是我的方法。

    public NegatedServerWebExchangeMatcher getURLsForDisabledCSRF() {
        return new NegatedServerWebExchangeMatcher(exchange -> ServerWebExchangeMatchers.pathMatchers(ALLOWED_PATHS).matches(exchange));
    }

现在在您的 getURLsForDisabledCSRF() 方法中委托 requireCsrfProtectionMatcher,如下所示:

        http
                .csrf().requireCsrfProtectionMatcher(getURLsForDisabledCSRF())

这是我的 Spring Cloud API Gateway 的安全配置类,它实际上使用了 Web Flux。

package com.ubaid.ms.gatewayserver.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.util.matcher.NegatedServerWebExchangeMatcher;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;

/**
 * <pre>
 * 1. Configure
 *      a. Authorize only authenticated requests except {@link SecurityConfig#ALLOWED_PATHS}
 *      b. OAuth 2.0 Resource Server support
 * 2. Disable CSRF on {@link SecurityConfig#ALLOWED_PATHS}
 * </pre>
 *
 * @author ubaid
 */
@Configuration
@EnableWebFluxSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfig {

    private final static String[] ALLOWED_PATHS = {"/token/**"};

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {

        http
                .csrf().requireCsrfProtectionMatcher(getURLsForDisabledCSRF())
                .and()
                .authorizeExchange()
                .pathMatchers(ALLOWED_PATHS).permitAll()
                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                .anyExchange()
                .authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt();

        return http.build();
    }

    public NegatedServerWebExchangeMatcher getURLsForDisabledCSRF() {
        return new NegatedServerWebExchangeMatcher(exchange -> ServerWebExchangeMatchers.pathMatchers(ALLOWED_PATHS).matches(exchange));
    }
}

注:Spring Cloud 版本:2020.0.2