Summary
It is common case when more flexibility is needed while using JwtGrantedAuthoritiesConverter, so I'm thinking of adding some kind of Function<Jwt, Collection<String>> grantedAuthoritiesMapper, so the consumers would be able to do something like:
Function<Jwt, Object> mapper = jwt -> jwt.<Map<String, Object>>getClaim(REALM_ACCESS).get(ROLES_ELEMENT);
converter.setGrantedAuthoritiesMapper(mapper);
I mean it could help to a lot of Keycloak users (for example) trying to provide role based authentication and it still would be possible to have default mapper like:
jwt -> jwt.getClaim(getAuthoritiesClaimName(jwt));
Just thinking if it could be a nice idea to implement such stuff, if you don't think it's common case just close this issue =)
Comment From: jzheaux
I agree that working with Keycloak is probably a common use case, @20fps.
Working with Keycloak's realm access claim yields a converter like so:
Converter<Jwt, Collection<GrantedAuthority>> converter = jwt -> {
Map<String, Object> realmAccess = jwt.getClaim("realm_access");
Collection<String> roles = realmAccess.get("roles");
return roles.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
};
which actually seems pretty simple.
Comparing that with:
JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter();
converter.setAuthorityPrefix("ROLE_");
converter.setGrantedAuthoritiesMapper(jwt -> {
Map<String, Object> realmAccess = jwt.getClaim("realm_access");
return realmAccess.get("roles");
});
I'm not really seeing it as a clear win.
Or, IOW, even if this were super-common, it seems like it's the same amount of custom code either way. Is there something I've overlooked?
One thing that you might consider is logging a ticket with Keycloak as I believe they have a Spring Boot Keycloak Adapter. This seems like a reasonable thing to add into it.
Comment From: 20fps
@jzheaux Yes, I actually have the same code, agree it's gonna be overlooked)