如何从资源服务器中的 Spring Security OAuht2 Boot 中提取声明?

How to extract claims from Spring Security OAuht2 Boot in the Resource Server?

我有一个使用 Identity Server 4! It is working as expected to authorize clients and resources from Node Js and .Net. Now I'm trying to add a Java spring Boot 2 API (jdk 1.8) as a Protected Resource. I have achieved that goal by using the OAuth2 Boot Documentation 在 .Net Core 中内置的授权服务器!到目前为止一切正常。现在,我需要从授权服务器生成的访问令牌中提取声明。这是 JWT 类型的 Bearer Token。我对此的实现如下:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends ResourceServerConfigurerAdapter {
  public String resourceId;

  @Autowired
  public SecurityConfiguration(@Value("${security.oauth2.resource.id}") String resourceId) {
    this.resourceId = resourceId;
  }

@Override
  public void configure(ResourceServerSecurityConfigurer resources) {
    resources.resourceId(this.resourceId);
}

  @Override
  public void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
        .csrf()
        .disable()
        .authorizeRequests()
        .antMatchers("/swagger-ui.html", "/webjars/**", "/swagger-resources/**", "/**/api-docs/**", "/actuator/**")
        .permitAll()
        .and()
        .authorizeRequests().anyRequest().fullyAuthenticated();
  }

问题是当我尝试访问控制器内的声明时,它们不可用。我已经检查了 DefaultAccessTokenConverter 中的默认 extractAuthentication 方法,在 spring 安全性内,实际上它忽略了所有非默认声明。我想到的是创建一个扩展 DefaultAccessToken 转换器的新转换器,如下所示:

@Component
public class CustomAccessTokenConverter extends DefaultAccessTokenConverter {

  @Override
  public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {
    OAuth2Authentication authentication = super.extractAuthentication(claims);
    authentication.setDetails(claims);
    return authentication;
  }
}

但我还没有弄清楚在哪里注入或引用这个新转换器。

不幸的是,Spring Boot auto-configuration 似乎没有提供替换 DefaultAccessTokenConverter 的方法,DefaultAccessTokenConverterRemoteTokenServices 中的默认标记转换器。要替换转换器,您必须替换默认创建的 RemoteTokenServices

如果你的转换器是一个 bean,你可以在你自己的 RemoteTokenServices 对象上设置它,然后你可以在 ResourceServerSecurityConfigurer 上设置它(这样它就可以应用于 OAuth2AuthenticationManager 幕后花絮):

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends ResourceServerConfigurerAdapter {
    // ...

    @Autowired
    private ResourceServerProperties resource;

    @Autowired
    private CustomAccessTokenConverter customConverter;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.tokenServices(customTokenServices());
        // ..
    }

    private RemoteTokenServices customTokenServices() {
        RemoteTokenServices services = new RemoteTokenServices();
        services.setAccessTokenConverter(this.customConverter);

        // configure based on .properties file 
        services.setCheckTokenEndpointUrl(this.resource.getTokenInfoUri());
        services.setClientId(this.resource.getClientId());
        services.setClientSecret(this.resource.getClientSecret());

        return services;
    }

    // ..