Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get role from nested value in Authentication attributes map #1132

Open
BramMeerten opened this issue Nov 10, 2022 · 3 comments
Open

Get role from nested value in Authentication attributes map #1132

BramMeerten opened this issue Nov 10, 2022 · 3 comments
Labels
info: workaround available A workaround is available for the issue status: under consideration The issue is being considered, but has not been accepted yet

Comments

@BramMeerten
Copy link

Feature description

The property micronaut.security.token.roles-name allows you to specify the authentication attributes map key for the user’s roles.

But my JWT token payload looks like this:

...
"realm_access": {
    "roles": [
      "manager",
      "offline_access",
      "uma_authorization"
    ]
  },
...

It would be useful to be able to specify a nested key. In this case that would be:
micronaut.security.token.roles-name: realm_access.roles

Relevant code can be found here: https://github.com/micronaut-projects/micronaut-security/blob/master/security/src/main/java/io/micronaut/security/token/DefaultRolesFinder.java#L81

A simular question (with workaround) has been posted on the micronaut gitter channel: https://gitter.im/micronautfw/questions?at=5e4501aab612cc7bb1643207

@BramMeerten
Copy link
Author

This is a workaround that I use:

@Singleton
@Replaces(DefaultRolesFinder.class)
public class RolesFinderReplacement extends DefaultRolesFinder {

    public static final String REALM_ACCESS = "realm_access";
    public static final String ROLES = "roles";

    private final TokenConfiguration tokenConfiguration;

    public RolesFinderReplacement(TokenConfiguration tokenConfiguration, TokenConfiguration tokenConfiguration1) {
        super(tokenConfiguration);
        this.tokenConfiguration = tokenConfiguration1;
    }

    @Override
    public List<String> resolveRoles(@Nullable Map<String, Object> attributes) {
        if (attributes != null) {
            var realmAccess = attributes.get(REALM_ACCESS);
            if (realmAccess instanceof Map) {
                var realmRoles = ((Map<?, ?>) realmAccess).get(ROLES);
                return super.resolveRoles(Map.of(tokenConfiguration.getRolesName(), realmRoles));
            }
        }

        return super.resolveRoles(attributes);
    }
}

In the gitter link in description is another workaround available.

@sdelamo sdelamo added the info: workaround available A workaround is available for the issue label Dec 20, 2022
@sdelamo
Copy link
Contributor

sdelamo commented Dec 20, 2022

I am not sure what we ca do. We created the RolesFinder API specifically so that users could create their own custom implementation as you did.

@sdelamo sdelamo added the status: under consideration The issue is being considered, but has not been accepted yet label Dec 20, 2022
@msincuba
Copy link

msincuba commented Jan 2, 2024

This is a workaround that I use:

@Singleton
@Replaces(DefaultRolesFinder.class)
public class RolesFinderReplacement extends DefaultRolesFinder {

    public static final String REALM_ACCESS = "realm_access";
    public static final String ROLES = "roles";

    private final TokenConfiguration tokenConfiguration;

    public RolesFinderReplacement(TokenConfiguration tokenConfiguration, TokenConfiguration tokenConfiguration1) {
        super(tokenConfiguration);
        this.tokenConfiguration = tokenConfiguration1;
    }

    @Override
    public List<String> resolveRoles(@Nullable Map<String, Object> attributes) {
        if (attributes != null) {
            var realmAccess = attributes.get(REALM_ACCESS);
            if (realmAccess instanceof Map) {
                var realmRoles = ((Map<?, ?>) realmAccess).get(ROLES);
                return super.resolveRoles(Map.of(tokenConfiguration.getRolesName(), realmRoles));
            }
        }

        return super.resolveRoles(attributes);
    }
}

In the gitter link in description is another workaround available.

I had the same issue on keycloak and realised that it's the role mapping issue. I had Token Claim Name as "realm_access.roles" instead of "roles" and my problem was solved after changing to roles.

Screenshot from 2024-01-02 16-19-32

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info: workaround available A workaround is available for the issue status: under consideration The issue is being considered, but has not been accepted yet
Projects
None yet
Development

No branches or pull requests

3 participants