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.

