Webflux 在特定 URL 上禁用 CSRF



这个想法是在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();
}
}

这应该可以做到

@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();
}

我为时已晚,但经过大量研究,我得到了一个不错的解决方案。

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

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

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

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

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));
}
}

注:春云版本:2020.0.2

config allowedOrigins:

@Bean
public WebFluxConfigurer corsConfigurer() {
return new WebFluxConfigurerComposite() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOrigins("/goodss")
.allowedMethods("*");
}
};
}

最新更新