I'm trying to use Keycloak to secure a Spring Boot API using Spring Security. The API is running on port 8080
and Keycloak is on port 8081
. This is my filter chain:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.requestMatchers(HttpMethod.POST, "/api/posts*").authenticated()
.anyRequest().permitAll()
.and()
.csrf().disable();
http.oauth2Login()
.and()
.logout()
.logoutSuccessUrl("/");
return http.build();
}
When I try to POST
to /api/posts
from Insomnia, It shows me the login screen even though I provided valid credentials.
(The access token is also there but it's not in the screenshot)
application.properties:
spring.security.oauth2.client.registration.keycloak.client-id=backend
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.scope=openid
spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8081/realms/test
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
CodePudding user response:
If you want to secure your API with tokens received from Keycloak, you should use the oauth2ResourceServer
directive in your security configuration. You're using oauth2Login
. So in the security filter chain, you should have something like this:
@Value("${pring.security.oauth2.client.provider.keycloak.issuer-uri}")
String issuerUri;
...
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer.jwt(jwt ->
jwt.decoder(JwtDecoders.fromIssuerLocation(issuerUri))
)
);
Have a look at this tutorial we've created at Curity that shows how to create a Spring Boot API protected with JWTs: https://curity.io/resources/learn/spring-boot-api/ You can have a look at the complete solution there.