0

---> .csrf((c) -> {c.disable();}) for the /api/** security filter chain caused the following to happen for an unknown reason:

The issue is not having the gateway route filters and resources servers not being called if there are multiple SecurityWebFilterChain beans.

Using Spring Boot 3.3.1, Spring Cloud 2023.0.2, and Webflux:

The application is split into a Webflux gateway and multiple resource servers that are configured with spring.cloud.gateway.routes that are registered with a Eureka instance. One SecurityWebFilterChain bean has a security matcher for "/api/" which should get forwarded to a resource server and a second SecurityWebFilterChain is for all other requests (default "/"). The "/api/**" bean has a higher order so it gets applied before the second bean.

Requests handled by the second SecurityWebFilterChain (/) bean applies the gateway route filters properly and forwards the request to the proper resource server. Requests handled by the API SecurityWebFilterChain (/api/) do not apply any gateway route filters or forward the request to the resource server although the response is a HTTP 200.

If I combined all requests into one SecurityWebFilterChain bean, everything works fine but I can't due to different configuration requirements for each path.

I'm trying to keep this concise with enough details to be helpful.

application.yml

gateway:
  filter:
    request-rate-limiter:
      enabled: true
  default-filters:
    - JWTRelay
    - name: RequestRateLimiter
  routes:
    - id: route1
      uri: lb://resourceserver1
      predicates:
        - Path=/resourceserver1/**
      filters:
        - StripPrefix=1
        - RemoveRequestHeader=Cookie
    - id: route2
      uri: lb://resourceserver2
      predicates:
        - Path=/resourceserver2/**
      filters:
        - StripPrefix=1
        - RemoveRequestHeader=Cookie            
    - id: api_route
      uri: lb://resourceserverapi
      predicates:
        - Path=/api/**
      filters:
        - StripPrefix=1
        - RemoveRequestHeader=Cookie    

SecurityConfig.java

@Order(Ordered.HIGHEST_PRECEDENCE)                                                      
@Bean
SecurityWebFilterChain apiHttpSecurity(ServerHttpSecurity http) {
    http
        .securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**"))      
        .authorizeExchange((exchanges) -> exchanges
            .anyExchange().authenticated()
        )
        .....                      
    return http.build();
}

@Bean
SecurityWebFilterChain webHttpSecurity(ServerHttpSecurity http) {                       
    http
        .authorizeExchange((exchanges) -> exchanges
            .anyExchange().authenticated()
        )
        .....                                               
    return http.build();
}

Logs when it works:

Weights attr: {} Pattern "[/services/resourceserver1/]" does not match against value "/resourceserver2/foo/" Pattern "[/services/resourceserver2/]" does not match against value "/resourceserver2/foo/" Pattern "[/services/api/]" does not match against value "/resourceserver2/foo/" Pattern "[/resourceserver1/]" does not match against value "/resourceserver2/foo/" Pattern "/resourceserver2/**" matches against value "/resourceserver2/foo/" Route matched: route2 ...

Logs when it doesn't work for /api/**:

Weights attr: {} ---no more logs---

I would expect to have the spring.cloud.gateway.routes configured to be applied to all SecurityWebFilterChain beans.

Request flow through the filter chains:

-> /api/foo -> SecurityWebFilterChain (/api/**) -> Gateway routes -> resourceserverapi

-> /resourceserver1/foo -> SecurityWebFilterChain (/**) -> Gateway routes -> resourceserver1

0