My Goal is spring cloud gateway should connect to keycloak and get authenticated and route it to client method
Referred Blog [/][1]
spring cloud gateway works as expected and User also authenticated by keycloak. But why securitycontextholder assigned as anonymous securitycontext for authenticated users.below is security chain at client end
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
}
2025-02-01 12:53:38.420 [,] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext 2025-02-01 12:53:38.422 [,] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Using 'text/html', given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, /;q=0.8, application/signed-exchange;v=b3;q=0.7] and supported [text/plain, /, application/json, application/*+json] 2025-02-01 12:53:38.422 [,] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Writing ["WebAuthenticationDetails [RemoteIpAddress=10.0.0.159, SessionId=null] Scopes: [ROLE_ANONYMOUS]"]
How can we avoid this?
My Goal is spring cloud gateway should connect to keycloak and get authenticated and route it to client method
Referred Blog [https://piotrminkowski/2024/03/01/microservices-with-spring-cloud-gateway-oauth2-and-keycloak/][1]
spring cloud gateway works as expected and User also authenticated by keycloak. But why securitycontextholder assigned as anonymous securitycontext for authenticated users.below is security chain at client end
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
}
2025-02-01 12:53:38.420 [,] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext 2025-02-01 12:53:38.422 [,] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Using 'text/html', given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, /;q=0.8, application/signed-exchange;v=b3;q=0.7] and supported [text/plain, /, application/json, application/*+json] 2025-02-01 12:53:38.422 [,] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Writing ["WebAuthenticationDetails [RemoteIpAddress=10.0.0.159, SessionId=null] Scopes: [ROLE_ANONYMOUS]"]
How can we avoid this?
Share Improve this question edited Feb 2 at 21:11 dur 17k26 gold badges89 silver badges143 bronze badges asked Feb 1 at 20:58 Sharmi467Sharmi467 1 2- Yes @ch4mp , even i tried this spring.cloud.gateway.default-filters[0]=DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin spring.cloud.gateway.default-filters[1]=TokenRelay spring.cloud.gateway.default-filters[2]=SaveSession – Sharmi467 Commented Feb 2 at 0:26
- Thanks @ch4mp issue is TokenRelay=. my code is not forwarding this token to OauthResource server . After adding this .route("hello-route", r -> r.path("/hello" .filters(f -> f.tokenRelay() ) able to forward toekn. – Sharmi467 Commented Feb 3 at 1:16
1 Answer
Reset to default 0When a user is authenticated with oauth2Login
on a Spring Cloud Gateway instance standing in front of REST services configured with oauth2ResourceServer
, you have to make sure that the "routes" to this downstream services are configured with the TokenRelay=
filter on the Gateway (the trailing =
is important).
When routing a request, this TokenRelay
filter replaces the session cookie set by oauth2Login
with a Bearer
authorization header containing the access token in the session for an authenticated user.
As a side note, there is a lot to say about the article you linked. For instance:
oauth2Login
andoauth2ResourceServer
shouldn't be mixed in the same filter chain: the first requires state (session), the second is stateless by nature- scopes are not roles. Keycloak has built-in support for users' roles at realm and client levels. Implementing RBAC for users with client scopes just because Spring Security default authentication converter builds authorities from the scope claim is hardly sustainable.
- fine-grained access control should be tested in unit tests (
@WebMvcTest
or@WebFluxTest
) using mocked authentications, not in integration tests (@SpringBootTest
) with test containers which are way too slow. See my Baeldung article for details - relying on the default access control rule (
isAuthenticated()
for all requests) and on the default status for unauthorized requests to a filter chain withoauth2Login
is a bad idea on a Gateway for a REST API:- all access decisions should be taken by the downstream resource servers (the gateway should
permitAll()
requests routed with theTokenRelay
filter) - a REST API should return
401 Unauthorized
when an anonymous request is sent to a protected resource, not302 Redirect to Login
suited for server-side rendered applications (Thymeleaf, JSP, etc...)
- all access decisions should be taken by the downstream resource servers (the gateway should
I believe my OAuth2 BFF tutorial on Baeldung to be based on more experience with OAuth2.