Created
December 16, 2023 10:36
-
-
Save lofidewanto/4dc064d915523bf73453845de572fd46 to your computer and use it in GitHub Desktop.
Konfiguration für die Zusammenführung von Rollen und Scopes (OAuth2) in Spring Security 6.2 und Spring Boot 3.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.test; | |
import java.util.Collection; | |
import java.util.HashSet; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.stream.Collectors; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | |
import org.springframework.security.core.GrantedAuthority; | |
import org.springframework.security.core.authority.SimpleGrantedAuthority; | |
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; | |
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; | |
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; | |
@Configuration | |
@EnableWebSecurity | |
public class SecurityConfiguration { | |
private static final String REALM_ACCESS_CLAIM = "realm_access"; | |
private static final String ROLES_CLAIM = "roles"; | |
private static final String RESOURCE_ACCESS_CLAIM = "resource_access"; | |
@Value("${spring.security.oauth2.client.registration.keycloak.client-id}") | |
private String clientId; | |
@Bean | |
GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak() { | |
return authorities -> { | |
Set<GrantedAuthority> mappedAuthorities = new HashSet<>(); | |
var authority = authorities.iterator().next(); | |
boolean isOidc = authority instanceof OidcUserAuthority; | |
if (isOidc) { | |
var oidcUserAuthority = (OidcUserAuthority) authority; | |
var userInfo = oidcUserAuthority.getUserInfo(); | |
if (userInfo.hasClaim(REALM_ACCESS_CLAIM)) { | |
var realmAccess = userInfo.getClaimAsMap(REALM_ACCESS_CLAIM); | |
@SuppressWarnings("unchecked") | |
var roles = (Collection<String>) realmAccess.get(ROLES_CLAIM); | |
mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles)); | |
} | |
if (userInfo.hasClaim(RESOURCE_ACCESS_CLAIM)) { | |
var resourceAccess = userInfo.getClaimAsMap(RESOURCE_ACCESS_CLAIM); | |
if (resourceAccess.containsKey(clientId)) { | |
@SuppressWarnings("unchecked") | |
var roles = (Collection<String>) ((Map<?, ?>) resourceAccess.get(clientId)) | |
.get(ROLES_CLAIM); | |
mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles)); | |
} | |
} | |
} else { | |
var oauth2UserAuthority = (OAuth2UserAuthority) authority; | |
Map<String, Object> userAttributes = oauth2UserAuthority.getAttributes(); | |
if (userAttributes.containsKey(REALM_ACCESS_CLAIM)) { | |
@SuppressWarnings("unchecked") | |
var realmAccess = (Map<String, Object>) userAttributes.get(REALM_ACCESS_CLAIM); | |
@SuppressWarnings("unchecked") | |
var roles = (Collection<String>) realmAccess.get(ROLES_CLAIM); | |
mappedAuthorities.addAll(generateAuthoritiesFromClaim(roles)); | |
} | |
} | |
return mappedAuthorities; | |
}; | |
} | |
private Collection<GrantedAuthority> generateAuthoritiesFromClaim(Collection<String> roles) { | |
return roles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toList()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment