Reputation: 21
I am using spring-cloud-gateway as an oauth client to implement a BFF application and I am not able to bypass specific url patterns from oauth flows.
Based on my understanding, the filter chain configured below should not trigger oauth for requests /passthru/api/public as it explicitly allows permitAll() for "/passthru/**"
. However, when I hit this endpoint in the browser, it redirected me to the Auth server login page.
Also seen in logs, the match is found "Checking match of request : '/passthru/api/public'; against '/**'"
where as it should have been found for /passthru/**
.
I have tried CHAT-GPT and DEEPSEEK among others, and they all seem to suggest what I have already implemented.
@Bean
@Order(-1)
public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/passthru/**").permitAll() // Allow public access to certain endpoints
.anyRequest().authenticated() // Require authentication for all other endpoints
)
.oauth2Login(Customizer.withDefaults() // Custom login page for OAuth2
)
.logout(logout -> logout
.logoutSuccessUrl("/") // Redirect to home page after logout
)
.csrf(csrf -> csrf.disable()); // Disable CSRF for simplicity (not recommended for production)
return http.build();
}
> [ca59c5ab-1] HTTP GET "/passthru/api/public"
Request 'GET /passthru/api/public' doesn't match 'null /oauth2/authorization/{registrationId}'
Request 'GET /passthru/api/public' doesn't match 'null /oauth2/authorization/{registrationId}'
Request 'GET /passthru/api/public' doesn't match 'null /login/oauth2/code/{registrationId}'
Request 'GET /passthru/api/public' doesn't match 'GET /default-ui.css'
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=GET}
Request 'GET /passthru/api/public' doesn't match 'GET /login'
No matches found
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=GET}
Request 'GET /passthru/api/public' doesn't match 'GET /logout'
No matches found
Created new WebSession.
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=POST}
Request 'GET /passthru/api/public' doesn't match 'POST /logout'
No matches found
Checking authorization on '/passthru/api/public' using org.springframework.security.authorization.AuthenticatedReactiveAuthorizationManager@55ded0ee
No SecurityContext found in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@7bde73c1'
Authorization failed: Access Denied
No SecurityContext found in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@7bde73c1'
Trying to match using AndServerWebExchangeMatcher{matchers=[NegatedServerWebExchangeMatcher{matcher=org.springframework.security.config.web.server.ServerHttpSecurity$OAuth2LoginSpec$$Lambda$948/0x000000700152e7b8@50419914}, NegatedServerWebExchangeMatcher{matcher=AndServerWebExchangeMatcher{matchers=[OrServerWebExchangeMatcher{matchers=[PathMatcherServerWebExchangeMatcher{pattern='/login', method=null}, PathMatcherServerWebExchangeMatcher{pattern='/favicon.ico', method=null}]}, AndServerWebExchangeMatcher{matchers=[NegatedServerWebExchangeMatcher{matcher=org.springframework.security.config.web.server.ServerHttpSecurity$OAuth2LoginSpec$$Lambda$948/0x000000700152e7b8@50419914}, MediaTypeRequestMatcher [matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]}]}}]}
Trying to match using NegatedServerWebExchangeMatcher{matcher=org.springframework.security.config.web.server.ServerHttpSecurity$OAuth2LoginSpec$$Lambda$948/0x000000700152e7b8@50419914}
matches = true
Trying to match using NegatedServerWebExchangeMatcher{matcher=AndServerWebExchangeMatcher{matchers=[OrServerWebExchangeMatcher{matchers=[PathMatcherServerWebExchangeMatcher{pattern='/login', method=null}, PathMatcherServerWebExchangeMatcher{pattern='/favicon.ico', method=null}]}, AndServerWebExchangeMatcher{matchers=[NegatedServerWebExchangeMatcher{matcher=org.springframework.security.config.web.server.ServerHttpSecurity$OAuth2LoginSpec$$Lambda$948/0x000000700152e7b8@50419914}, MediaTypeRequestMatcher [matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]}]}}
Trying to match using OrServerWebExchangeMatcher{matchers=[PathMatcherServerWebExchangeMatcher{pattern='/login', method=null}, PathMatcherServerWebExchangeMatcher{pattern='/favicon.ico', method=null}]}
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=null}
Request 'GET /passthru/api/public' doesn't match 'null /login'
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/favicon.ico', method=null}
Request 'GET /passthru/api/public' doesn't match 'null /favicon.ico'
No matches found
Did not match
matches = true
All requestMatchers returned true
Match found! Executing org.springframework.security.web.server.authentication.RedirectServerAuthenticationEntryPoint@628e22f1
Trying to match using OrServerWebExchangeMatcher{matchers=[PathMatcherServerWebExchangeMatcher{pattern='/**', method=GET}]}
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/**', method=GET}
Checking match of request : '/passthru/api/public'; against '/**'
matched
Trying to match using NegatedServerWebExchangeMatcher{matcher=OrServerWebExchangeMatcher{matchers=[PathMatcherServerWebExchangeMatcher{pattern='/favicon.*', method=null}]}}
Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/favicon.*', method=null}
Request 'GET /passthru/api/public' doesn't match 'null /favicon.*'
No matches found
matches = true
Trying to match using MediaTypeRequestMatcher [matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[*/*]]
httpRequestMediaTypes=[text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8]
Processing text/html
text/html .isCompatibleWith text/html = true
All requestMatchers returned true
Request added to WebSession: '/passthru/api/public'
Redirecting to '/oauth2/authorization/localauth'
[ca59c5ab-1] Completed 302 FOUND
[ca59c5ab-2] HTTP GET "/oauth2/authorization/localauth"
Checking match of request : '/oauth2/authorization/localauth'; against '/oauth2/authorization/{registrationId}'
Redirecting to 'http://localhost:9000/oauth2/authorize?response_type=code&client_id=<..removed content...>
[ca59c5ab-2] Completed 302 FOUND
Upvotes: 0
Views: 24
Reputation: 21
On further debugging, I realized that the SecurityFilterChain bean was not recognized, hence the matcher was never invoked.
I was able to make it work with the following changes:
spring-cloud.version=2024.0.0 with spring-boot-starter-webflux
Using @EnableWebFluxSecurity instead of @EnableWebSecurity and setting up the filter chain as
@Bean
public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http){...}
Upvotes: 0