Nick Melis
Nick Melis

Reputation: 453

How to create custom claims in JWT using spring-authorization-server

I'm building an OAuth2 authorization server based on the experimental Spring project Spring Authorization Server

My use case is quite simple, fetch users from a DB, and based on some properties of the user, set some custom claims in the JWT being produced. I haven't found a way to do so with Spring Authorization Server, the only way I could work out is to inject a jwtCustomizer object as part of the JwtEncoder bean definition:

  @Bean
  public JwtEncoder jwtEncoder(CryptoKeySource keySource) {
    NimbusJwsEncoder jwtEncoder = new NimbusJwsEncoder(keySource);
    jwtEncoder.setJwtCustomizer((headersBuilder, claimsBuilder) -> {
      // Inject some headers and claims...
    });
    return jwtEncoder;
  }

This obviously doesn't give me access to users information, therefore I can't set the claims I need at this point. Did anyone manage to solve this problem?

Upvotes: 11

Views: 6646

Answers (2)

Yunier Broche Guevara
Yunier Broche Guevara

Reputation: 309

The solution for this is in a test of the library

    @Bean
    OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer() {
        return context -> {
            if (context.getTokenType().getValue().equals(OidcParameterNames.ID_TOKEN)) {
                Authentication principal = context.getPrincipal();
                Set<String> authorities = principal.getAuthorities().stream()
                        .map(GrantedAuthority::getAuthority)
                        .collect(Collectors.toSet());
                context.getClaims().claim(AUTHORITIES_CLAIM, authorities);
            }
        };
    }

Upvotes: 19

Nikolai  Shevchenko
Nikolai Shevchenko

Reputation: 7521

You can try following way. Though it is Kotlin code, not Java, but approach should be clear:

import org.springframework.security.oauth2.provider.token.TokenEnhancer

class UserTokenEnhancer : TokenEnhancer {
    
    override fun enhance(accessToken: OAuth2AccessToken,
                         authentication: OAuth2Authentication): OAuth2AccessToken {

        val username = authentication.userAuthentication.name
        val additionalInfo = mapOf( /* populate with some data for given username */ )

        (accessToken as DefaultOAuth2AccessToken).additionalInformation = additionalInfo
        return accessToken
    }
}

Then just register bean:

@Bean
fun userTokenEnhancer(): TokenEnhancer {
    return UserTokenEnhancer()
}

Upvotes: 0

Related Questions