KeycloakGrantedAuthoritiesConverter.java
package com.project.auth.config.auth.security;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class KeycloakGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
private static final String CLAIM_REALM_ACCESS = "realm_access";
private static final String CLAIM_ROLES = "roles";
private static final String ROLE_PREFIX = "ROLE_";
private final JwtGrantedAuthoritiesConverter scopeConverter = new JwtGrantedAuthoritiesConverter();
@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
Set<GrantedAuthority> authorities = new LinkedHashSet<>(scopeConverter.convert(jwt));
for (String role : realmRoles(jwt)) {
authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + role));
}
return Set.copyOf(authorities);
}
private static List<String> realmRoles(Jwt jwt) {
Map<String, Object> realmAccess = jwt.getClaim(CLAIM_REALM_ACCESS);
if (realmAccess == null) {
return List.of();
}
Object roles = realmAccess.get(CLAIM_ROLES);
if (!(roles instanceof Collection<?> roleValues)) {
return List.of();
}
return roleValues.stream()
.filter(String.class::isInstance)
.map(String.class::cast)
.filter(role -> !role.isBlank())
.toList();
}
}