Nuestros mejores investigadores han agotado sus provisiones de café, en su búsqueda todo el tiempo por la solución, hasta que Nora encontró el arreglo en GitLab y ahora la comparte aquí.
Solución:
A través de la consola de administración de keycloak, puede crear un mapeador de tokens de tipo Rol de dominio de usuario con el nombre de reclamo “autoridades” para su cliente “demo-client”. Luego, el token de acceso contiene los nombres de los roles en este attribute y sin costumbre Convertidor de token de acceso predeterminado se necesita
Encontré una solución por mí mismo justo después de formular esta pregunta aquí. A veces ayuda tratar de expresar un problema.
La solución es anular el DefaultAccessTokenConverter para enseñarle cómo leer el campo “realm_access”. Es feo pero funciona:
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception
resources.resourceId("demo-client");
RemoteTokenServices tokenServices = new RemoteTokenServices();
tokenServices.setCheckTokenEndpointUrl(
"http://localhost:8280/auth/realms/demo-realm/protocol/openid-connect/token/introspect");
tokenServices.setClientId("demo-client");
tokenServices.setClientSecret("80e19056-7770-4a4a-a3c4-06d8ac8792ef");
tokenServices.setAccessTokenConverter(new KeycloakAccessTokenConverter());
resources.tokenServices(tokenServices);
private class KeycloakAccessTokenConverter extends DefaultAccessTokenConverter
@Override
public OAuth2Authentication extractAuthentication(Map map)
OAuth2Authentication oAuth2Authentication = super.extractAuthentication(map);
Collection authorities = (Collection) oAuth2Authentication.getOAuth2Request().getAuthorities();
if (map.containsKey("realm_access"))
Map realm_access = (Map) map.get("realm_access");
if(realm_access.containsKey("roles"))
((Collection) realm_access.get("roles")).forEach(r -> authorities.add(new SimpleGrantedAuthority(r)));
return new OAuth2Authentication(oAuth2Authentication.getOAuth2Request(),oAuth2Authentication.getUserAuthentication());