micronaut-projects / micronaut-security

The official Micronaut security solution
Apache License 2.0
170 stars 126 forks source link

custom role claims in Id/Access tokens are missing in Micronaut generated JWTs #1558

Open deepu105 opened 8 months ago

deepu105 commented 8 months ago

Expected Behavior

Custom role claims should be added to generated JWTs

Actual Behaviour

When micronaut.security.authentication=cookie and if there are custom role claims in the IDToken from the IdP, they are not inlcuded in the JWT generated by JWTClaimsSetGenerator the below code is supposed to add all claims to the genrated JWT

    protected void populateWithAuthentication(JWTClaimsSet.Builder builder, Authentication authentication) {
        populateSub(builder, authentication);
        authentication.getAttributes().forEach(builder::claim);
        String rolesKey = tokenConfiguration.getRolesName();
        if (!rolesKey.equalsIgnoreCase(TokenConfiguration.DEFAULT_ROLES_NAME)) {
            builder.claim(ROLES_KEY, rolesKey);
        }
        builder.claim(rolesKey, authentication.getRoles());
    }

But it does not work since authentication.getRoles() always returns empty and hence the actual roles in original claim is overwritten.

The authentication.getRoles() call returns empty since DefaultOpenIdAuthenticationMapper has below implementation

  protected List<String> getRoles(String providerName, OpenIdTokenResponse tokenResponse, OpenIdClaims openIdClaims) {
      return Collections.emptyList();
  }

Is this implementation correct?

Steps To Reproduce

  1. Create an app mn create-app demo --features=security-jwt,security-oauth2
  2. Create custom claims with roles in the IdP
  3. add micronaut.security.token.roles-name=custom-roles in config
  4. check the JWT created by micronaut

Environment Information

Example Application

No response

Version

4.2.1

sdelamo commented 8 months ago

micronaut.security.authentication=idtoken will save the idtoken provided by the authentication provider in a cookie.

deepu105 commented 8 months ago

With idtoken, micronaut expects the client ID to be in the aud claim of an access token and access tokens from auth0 does not have that, thats why I switched to using cookie. Temporary I'm using a custom role finder to work around but regardless I think the roles should not be overwritten when using cookie.

deepu105 commented 8 months ago

Would it be ok to check if roles are present before overwriting in JWTClaimsSetGenerator? If acceptable, I can do a PR

protected void populateWithAuthentication(JWTClaimsSet.Builder builder, Authentication authentication) {
        populateSub(builder, authentication);
        authentication.getAttributes().forEach(builder::claim);
        String rolesKey = tokenConfiguration.getRolesName();
        if (!rolesKey.equalsIgnoreCase(TokenConfiguration.DEFAULT_ROLES_NAME)) {
            builder.claim(ROLES_KEY, rolesKey);
        }
        If (!authentication.getRoles().isEmpty()) {
            builder.claim(rolesKey, authentication.getRoles());
        }
    }