I'd like to hide Keycloak behind spring cloud gateway but still use it as OIDC provider. I've managed to permit /auth
(keycloak's) endpoint for that but now I'm fighting with http basic auth which IDK how to disable. Everytime I try to hit any other endpoint which should be protected by keycloak I get browser form login. With following config
@Bean
@Order(1)
SecurityWebFilterChain publicEndpoints(final ServerHttpSecurity http) {
return http.authorizeExchange(auth ->
auth.pathMatchers("/auth", "/auth/**").permitAll())
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.cors(ServerHttpSecurity.CorsSpec::disable)
.formLogin(ServerHttpSecurity.FormLoginSpec::disable)
.headers(c -> c.frameOptions(ServerHttpSecurity.HeaderSpec.FrameOptionsSpec::disable))
.httpBasic(basic ->
basic.authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)))
.build();
}
@Bean
@Order(2)
SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http) {
return http.authorizeExchange(auth -> auth.anyExchange().authenticated())
.oauth2Login(withDefaults())
.oauth2ResourceServer((oauth2) -> oauth2.jwt(withDefaults()))
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.cors(ServerHttpSecurity.CorsSpec::disable)
.formLogin(ServerHttpSecurity.FormLoginSpec::disable)
.headers(c -> c.frameOptions(ServerHttpSecurity.HeaderSpec.FrameOptionsSpec::disable))
//.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
.build();
}
I get error on application startup:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.server.SecurityWebFilterChain]: Factory method 'publicEndpoints' threw exception with message: authenticationManager cannot be null
2025-03-06T15:35:01.907890843Z at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:199) ~[spring-beans-6.2.3.jar:6.2.3]
2025-03-06T15:35:01.907892426Z at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiateWithFactoryMethod(SimpleInstantiationStrategy.java:88) ~[spring-beans-6.2.3.jar:6.2.3]
2025-03-06T15:35:01.907893385Z at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:168) ~[spring-beans-6.2.3.jar:6.2.3]
2025-03-06T15:35:01.907894343Z at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-6.2.3.jar:6.2.3]
2025-03-06T15:35:01.907895260Z ... 39 common frames omitted
since I don't want to use any auth manager for publicEndpoints
I don't understand how to configure it to disable form login and use oauth
When using more than one filter chain, all but the last one in @Order
must contain a securityMatcher
definition to limit the requests it is applied to, or the next in @Order
are never tried. So, in your case, add .securityMatcher(...)
to your 1st filter chain.
As a side note, there are 2 issues with your second filter chain:
oauth2Login
& formLogin
are) and stateless (no session like oauth2ResourceServer
& basic
) request authorization in the same filter chainoauth2Login
)