【问题标题】:Implement TokenEnhancer for OAuth2 + JWT为 OAuth2 + JWT 实现 TokenEnhancer
【发布时间】:2020-11-03 05:17:42
【问题描述】:

我正在尝试使用以下代码为 OAuth2 + JWT 实现 TokenEnhancer:

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;
    }
}

你知道如何添加获取用户角色并将其添加到令牌有效负载中吗?

【问题讨论】:

  • 你可以使用 authentication.getUserAuthentication().getAuthorities()

标签: spring spring-security spring-security-oauth2


【解决方案1】:

您将无法使用该方法执行此操作,您必须为 JwtAccessTokenConverter 实现自定义行为。您可以在以下代码中看到一个示例:

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);
  }

}

您可以看到该代码和微服务的其余部分here

另一方面,在下面的link 中,您将能够看到一个完整集成的教程:JWT + Oauth2

【讨论】:

  • 感谢您的详细回答和回购。很有用
猜你喜欢
  • 2021-04-26
  • 2019-03-12
  • 1970-01-01
  • 2017-03-08
  • 2018-01-15
  • 2017-09-09
  • 2020-10-25
  • 2017-07-25
  • 2015-10-30
相关资源
最近更新 更多