1

I'm trying to implement TokenEnhancer for OAuth2 + JWT using this code:

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        final Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("organization", authentication.getName() + " test");
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
        return accessToken;
    }
}

Do you know how I can add get the user role and add it into the token payload?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

1 Answers1

2

You won't be able to do it using that approach, you have to implement your custom behaviour for JwtAccessTokenConverter. You can see an example in the following code:

public class CustomAccessTokenConverter extends JwtAccessTokenConverter {

  private static final String AUTHORITIES = "authorities";
  private static final String SCOPE = "scope";
  private static final String USERNAME = "username";
  private static final String ADDITIONAL_INFO = "additionalInfo";

  public CustomAccessTokenConverter() {
    super();
  }

  @Override
  public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    OAuth2AccessToken result = super.enhance(accessToken, authentication);
    result.getAdditionalInformation().putAll(getAdditionalInformation(authentication));
    return result;
  }


  @Override
  public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
    Map<String, Object> defaultInformation = (Map<String, Object>) super.convertAccessToken(token, authentication);
    return this.isRefreshToken(token) ? getRefreshTokenInformation(defaultInformation)
                                      : getAccessTokenInformation(defaultInformation);
  }

  /**
   * Filter the data included in the JWT access token
   */
  private Map<String, ?> getAccessTokenInformation(Map<String, Object> sourceInformation) {
    Map<String, Object> accessTokenInformation = new HashMap<>(sourceInformation);
    accessTokenInformation.keySet().removeIf(k -> asList(SCOPE).contains(k));
    return accessTokenInformation;
  }

  /**
   * Filter the data included in the JWT refresh token
   */
  private Map<String, ?> getRefreshTokenInformation(Map<String, Object> sourceInformation) {
    Map<String, Object> refreshTokenInformation = new HashMap<>(sourceInformation);
    refreshTokenInformation.keySet().removeIf(k -> asList(AUTHORITIES, SCOPE).contains(k));
    return refreshTokenInformation;
  }

  /**
   * Include an specific section with extra information in the returned {@link OAuth2AccessToken}
   */
  private Map<String, Object> getAdditionalInformation(OAuth2Authentication authentication) {
    Map<String, Object> authenticationAdditionalInformation = Map.ofEntries(
            entry(USERNAME, authentication.getUserAuthentication().getName()),
            entry(AUTHORITIES,
                    authentication.getAuthorities().stream()
                            .map(GrantedAuthority::getAuthority)
                            .collect(toSet()))
    );
    return Map.of(ADDITIONAL_INFO, authenticationAdditionalInformation);
  }

}

You can see that code and the rest of the microservice here.

On the other hand, in the following link you will be able to see a tutorial with a complete integration with: JWT + Oauth2

doctore
  • 3,855
  • 2
  • 29
  • 45