How to get Keycloack to Azure/EntraId to retreive claims/groups/roles SpringBoot

77 views Asked by At

I've configured a local instance of Keycloak to act as an Identity Broker (kind of a proxy) to Microsoft EntraID, previously known as Azure Active Directory, which is the actual Identity Provider) via Oauth2/OIDC.

I've succeeded in getting an example Spring Boot application to display basic identity information and roles through this setup. However, it will not return roles or groups, except default roles and scopes ROLE_USER, ROLE_USER, SCOPE_email, SCOPE_openid, SCOPE_profile.

I would like it to return roles I've configured specifically for the user. Is this possible?

Here's the relevant code:

application.properties:

server.port=9080

spring.security.oauth2.client.registration.oauth2-demo-thymeleaf-client.client-id=azure-client-provider
spring.security.oauth2.client.registration.oauth2-demo-thymeleaf-client.client-secret=xxxx
spring.security.oauth2.client.registration.oauth2-demo-thymeleaf-client.scope=openid, profile, roles
spring.security.oauth2.client.registration.oauth2-demo-thymeleaf-client.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.oauth2-demo-thymeleaf-client.redirect-uri=http://localhost:9080/login/oauth2/code/azure-client-provider
spring.security.oauth2.client.provider.oauth2-demo-thymeleaf-client.issuer-uri=http://localhost:8180/realms/demoBroker



@RestController
public class RoleController {

    @GetMapping("/roles")
    public String printScopes(@AuthenticationPrincipal OAuth2User oauth2User) {
        // Get the scopes from the OAuth2User object


        StringBuilder htmlContent = new StringBuilder("<html><body><h2>User Information</h2>");

        // Get user attributes
        String userId = oauth2User.getName();
        htmlContent.append("<p><strong>User ID:</strong> ").append(userId).append("</p>");

        // Get and append all attributes
        oauth2User.getAttributes().forEach((key, value) ->
                htmlContent.append("<p><strong>").append(key).append(":</strong> ").append(value).append("</p>"));

        htmlContent.append("</body></html>");

        // Include user authorities (roles)
        htmlContent.append("<p><strong>Authorities:</strong> ");
        oauth2User.getAuthorities().forEach(authority ->
                htmlContent.append(authority.getAuthority()).append(", "));
        htmlContent.append("</p>");

        System.out.println("User Info (HTML):\n" + htmlContent.toString());
        return htmlContent.toString();
    }
}

Output:

User Information
User ID: 60e9bd60-xxx

at_hash: gGDXPZxxx

sub: 60e9bdxxx

email_verified: false

iss: http://localhost:8180/realms/demoBroker

typ: ID

preferred_username: xxxxx

given_name: xxxxx

nonce: xxx

sid: xxxx

aud: [azure-client-provider]

acr: 0

azp: azure-client-provider

auth_time: 2024-03-09T15:27:45Z

name: xxxx

exp: 2024-03-09T15:45:25Z

session_state: fababa49-6ca7-42d5-911d-7379c6719bf6

family_name: xxxx

iat: 2024-03-09T15:40:25Z

email: [email protected]

jti: xxxx

Authorities: ROLE_USER, SCOPE_email, SCOPE_openid, SCOPE_profile,

It should be showing some roles I've assigned to the user such as Application Adminstrator, etc.

Any thoughts?

1

There are 1 answers

1
ch4mp On

Two steps to have roles from EntraID as Spring Security authorities in your OAuth2 client with oauth2Login:

Instead of the second step, you could consider using my starter which will configure the authorities mapper for you, based on application properties you provide (claims to extract roles from, optional prefix and case transformation you want).