覆盖 JWT OAuth 令牌的 UserAuthenticationConverter

Override UserAuthenticationConverter for JWT OAuth Tokens

我正在尝试创建一个 spring 受 oauth2 保护的资源服务器。

我正在为我的 auth2 服务使用 auth0,我有一个 api 和配置了范围的客户端。

我有一个资源服务器,大部分 工作。它是安全的,我可以使用 @EnableGlobalMethodSecurity 和 @PreAuthorize("#oauth2.hasScope('profile:read')") 来限制对该范围内令牌的访问。

但是,当我尝试获取 Principal 或 OAuth2Authentication 时,它们都为空。我已将资源服务器配置为使用 JWK key-set-uri。

我怀疑这与 DefaultUserAuthenticationConverter 试图从 JWT 中读取 'user_name' 声明有关,但它需要从 'sub' 声明中读取它,我不知道不知道如何改变这种行为。

首先创建一个UserAuthenticationConverter:

public class OidcUserAuthenticationConverter implements UserAuthenticationConverter {

    final String SUB = "sub";

    @Override
    public Map<String, ?> convertUserAuthentication(Authentication userAuthentication) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Authentication extractAuthentication(Map<String, ?> map) {
        if (map.containsKey(SUB)) {
            Object principal = map.get(SUB);
            Collection<? extends GrantedAuthority> authorities = null;
            return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
        }
        return null;
    }
}

然后配置 spring 以像这样使用它:

@Configuration
public class OidcJwkTokenStoreConfiguration {
    private final ResourceServerProperties resource;

    public OidcJwkTokenStoreConfiguration(ResourceServerProperties resource) {
        this.resource = resource;
    }

    @Bean
    public TokenStore jwkTokenStore() {
        DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
        tokenConverter.setUserTokenConverter(new OidcUserAuthenticationConverter());
        return new JwkTokenStore(this.resource.getJwk().getKeySetUri(), tokenConverter);
    }
}