I'm currently trying to implement security for a simple Spring Boot Back-End application. For that I intended to use Keycloak in combination with Spring Security. After trying a dozens of tutorial set-ups (just a basic filter / SecurityConfig), I'm left clueless as to why the SecurityFilterChain
won't work.
As a reference - the following are my dependencies:
all with Spring Boot 3.1.0! Due to the fact that the online material was from the last two years, I also tried different versions through (e.g. <spring-security.version>6.1.1</spring-security.version>
, etc.)
As to my application.properties
I added the most basic set-up:
spring.security.oauth2.client.registration.keycloak.client-id=[client-id]
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:8080/realms/dev
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
That's that! Now onto the different approaches I've went through unsuccessfully:
On there it specified the SecurityConfig to be used with a @Bean
returning a SecurityFilterChain
:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/customers*")
.hasRole("USER")
.anyRequest()
.permitAll();
http.oauth2Login()
.and()
.logout()
.addLogoutHandler(keycloakLogoutHandler)
.logoutSuccessUrl("/");
http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
... Apparently, 'authorizeRequests()'
is deprecated. Same applies for 'oauth2Login()'
(even marked for removal)!
2. GitHub Issue #10187 discussion
In the before-mentioned issue, a in-depth discussion broke out with lots of members sharing their code snippet. It's a very recent topic (2022) and thus I thought it would still apply to current standards.
@Configuration
@RequiredArgsConstructor
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final KeycloakLogoutHandler keycloakLogoutHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() //
.anyRequest().fullyAuthenticated() //
.and().oauth2Client() //
.and().oauth2Login().tokenEndpoint().and().userInfoEndpoint().userAuthoritiesMapper(userAuthoritiesMapper()) //
.and().and()
.logout().addLogoutHandler(keycloakLogoutHandler)
;
}
private GrantedAuthoritiesMapper userAuthoritiesMapper() {
[...]
I played with something along those lines. Again... Besides the known culprits marked as deprecated
(oauth2Client()
, oauth2Login()
, etc.) the big issue was WebSecurityConfigurerAdapter
is ALSO deprecated. When opening issue #12514 I was then informed that I should proceed with a SecurityFilterChain
similar to the first approach.
Either way, I've burnt through approximately 10+ tutorials now and am not able to find one working project which is - considering the size of KeyCloak - very odd. The only good information I found was that the old KeyCloak adapters were deprecated as of last year... though I haven't used them as you can see above.
Is anyone able to help me out? I want to set-up a SIMPLE SecurityConfig
to build by base upon. Just fetching the bearer token (btw KeyCloak related set-up works) from the request, then validating the JWT and comparing the user roles / permissions to the needed role on an endpoint (preferably not a global setting, but a local one per endpoint basis).
If your Spring app just acts as an resource server, see my example here: https://github.com/dasniko/keycloak-bookshop-demo/tree/master/msgbroker
In the dependencies, there's just the org.springframework.boot:spring-boot-starter-oauth2-resource-server
.
The application.properties
just need the spring.security.oauth2.resourceserver.jwt.issuer-uri
configured and the SecurityConfig class is also small and lean.