I am trying to implement RBAC on my Spring Boot resource server. Previously I used Keycloak adapters, but now that they are deprecated I am having issues. I have followed the solution proposed here: https://stackoverflow.com/a/74572732/16489856, but it seems like that my configuration is wrong somehow.
Here is my Spring Security configuration:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors().disable()
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/workstations").hasRole("USER")
.anyRequest().authenticated();
http
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
public interface Jwt2AuthoritiesConverter extends Converter<Jwt, Collection<? extends GrantedAuthority>> {
}
@SuppressWarnings("unchecked")
@Bean
public Jwt2AuthoritiesConverter authoritiesConverter() {
// Roles are taken from realm_access.roles
return jwt -> {
final var realmAccess = (Map<String, Object>) jwt.getClaims().getOrDefault("realm_access", Map.of());
final var realmRoles = (Collection<String>) realmAccess.getOrDefault("roles", List.of());
return realmRoles.stream().map(SimpleGrantedAuthority::new).toList();
};
}
public interface Jwt2AuthenticationConverter extends Converter<Jwt, AbstractAuthenticationToken> {
}
@Bean
public Jwt2AuthenticationConverter authenticationConverter(Jwt2AuthoritiesConverter authoritiesConverter) {
return jwt -> new JwtAuthenticationToken(jwt, authoritiesConverter.convert(jwt));
}
}
Roles are properly set, if I print them like so:
Jwt jwt = (Jwt) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Map<String, Object> resourceAccess = jwt.getClaim("realm_access");
Collection<String> resourceRoles = (Collection<String>) resourceAccess.get("roles");
System.out.println((Collection<String>) resourceAccess.get("roles"));
I get:
[default-roles-spring_reservations_realm_0, offline_access, uma_authorization, USER]
which is correct.
However, when I access /workstation
endpoint, with a user that has the USER
role, it fails with 403 forbidden status, how can I fix this?