Spring boot 如何使用客户端\ U凭据从资源服务器访问另一个oauth2资源?

Spring boot 如何使用客户端\ U凭据从资源服务器访问另一个oauth2资源?,spring-boot,spring-security,spring-security-oauth2,spring-webflux,Spring Boot,Spring Security,Spring Security Oauth2,Spring Webflux,我想使用客户端\u凭据从反应式资源服务器访问另一个受oauth2保护的资源。我使用发出的令牌访问资源服务器的部分正在工作,但没有使用webclient调用其他资源 使用未经身份验证的服务器OAuth2AuthorizedClient存储我获取的服务器WebExchange必须为null,使用经身份验证的PrincipalServerOAuth2AuthorizedClient存储我获取的principalName必须为null 只要我将客户机作为CommandLineRunner调用,使用就可以

我想使用客户端\u凭据从反应式资源服务器访问另一个受oauth2保护的资源。我使用发出的令牌访问资源服务器的部分正在工作,但没有使用webclient调用其他资源

使用未经身份验证的服务器OAuth2AuthorizedClient存储我获取的
服务器WebExchange必须为null
,使用经身份验证的PrincipalServerOAuth2AuthorizedClient存储我获取的
principalName必须为null

只要我将客户机作为
CommandLineRunner
调用,使用就可以工作。我在这里找到的关于stackoverflow的其他建议都不起作用

我错过了什么?我使用的是Spring Security 5.2.0和Spring Boot 2.2.0

客户端配置:

@配置
公共类ClientSecurityConfig{
//未经身份验证的服务器OAuth2AuthorizedClient存储版本
@豆子
网络客户端网络客户端(ReactiveClientRegistration存储库clientRegistrations){
服务器OAuth2AuthorizedClientExchangeFilterFunction oauth=
新服务器OAuth2AuthorizedClientChangeFilterFunction(clientRegistrations,新的未经验证的服务器OAuth2AuthorizedClientRepository());
返回WebClient.builder()
.filter(oauth)
.build();
}
@豆子
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider(CustomClientConfig clientConfig){
返回ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials(clientCredentialsGrantBuilder->
clientCredentialsGrantBuilder.accessTokenResponseClient(新CustomClient(clientConfig))//用于向adfs服务器发送额外参数
.build();
}
//AuthenticatedPrincipalServerOAuth2AuthorizedClient存储版本
@豆子
网络客户端网络客户端(ReactiveOAuth2AuthorizedClientManager授权客户端管理器){
服务器OAuth2AuthorizedClientExchangeFilterFunction oauth=
新服务器OAuth2AuthorizedClientChangeFilterFunction(authorizedClientManager);
返回WebClient.builder()
.filter(oauth)
.build();
}
}
@豆子
ReactiveOAuth2AuthorizedClientManager授权dClientManager(
反应clientRegistrationRepository clientRegistrationRepository,
服务器OAuth2AuthorizedClient存储授权客户端存储,CustomClientConfig客户端配置){
反应OAuth2AuthorizedClient提供程序AuthorizedClient提供程序=
ReactiveOAuth2AuthorizedClientProviderBuilder.builder()的
.clientCredentials(clientCredentialsGrantBuilder->
clientCredentialsGrantBuilder.accessTokenResponseClient(新CustomClient(clientConfig))//用于向adfs服务器发送额外参数
.build();
DefaultReactiveOAuth2AuthorizedClientManager授权dClientManager=
新的DefaultReactiveOAuth2AuthorizedClient管理器(clientRegistrationRepository,AuthorizedClient存储库);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
返回授权客户管理器;
}
}
ResourceServerConfig:

@EnableWebFluxSecurity
类ResourceServerConfig{
@豆子
公共安全WebFilterChain springSecurityFilterChain(ServerHttpSecurity http){
http
.授权交换(交换->
交换
.pathMatchers(“/actuators/**”,“/api/v1”).permitAll()
.pathMatchers(“/api/v1/**”).hasAuthority(“范围读取”)
.anyExchange().authenticated()
)
.formLogin().disable()
.httpBasic().disable()
.oauth2Client(带默认值())
.oauth2ResourceServer().jwt();
返回http.build();
}
@RestController()
@请求映射(“/api/v1”)
静态类Ctrl{
最终静态记录器=LoggerFactory.getLogger(Ctrl.class);
最终网络客户网络客户;
public Ctrl(网络客户端网络客户端){
this.webClient=webClient;
}
@请求映射(“受保护”)
Mono保护(@RequestParam字符串数据){
返回webClient.post()
.uri(“https://other-oauth2-protected-resource")
.attributes(clientRegistrationId(“myclient”))
.bodyValue(“{\”数据\”:\“+数据+“\”}”)
.retrieve()
.bodytomino(JsonNode.class);
}
}
}
application.yml:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://adfsserver.com/adfs/services/trust
          jwk-set-uri: https://adfsserver.com/adfs/discovery/keys
      client:
        registration:
          myclient:
            provider: adfs
            client-id: <client-id>
            client-secret: <client-secret>
            authorization-grant-type: client_credentials
            scope: read
        provider:
          adfs:
            token-uri: https://adfsserver.com/adfs/oauth2/token
            jwk-set-uri: https://adfsserver.com/adfs/discovery/keys
spring:
安全:
oauth2:
资源服务器:
jwt:
发卡机构uri:http://adfsserver.com/adfs/services/trust
jwk集uri:https://adfsserver.com/adfs/discovery/keys
客户:
注册:
我的客户:
提供者:adfs
客户端id:
客户机密:
授权授予类型:客户端\u凭据
范围:阅读
供应商:
ADF:
令牌uri:https://adfsserver.com/adfs/oauth2/token
jwk集uri:https://adfsserver.com/adfs/discovery/keys

这是Spring项目贡献者最近修复的一部分,但遗憾的是,Spring官方文档尚未更新

通常的servlet方法是 如果您喜欢选择“反应式”方法,那么配置webclient只需要两个bean:

  • AuthorizedClientManager Bean,以及
  • webclientbean

  • 您可以参考my,它具有所有必需的配置。

    似乎缺少AuthorizedClientServiceOAuth2AuthorizedClientManager的被动对应项;请检查我的答案(尽管我知道答案是正确的)
      @Bean
      public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
          ReactiveClientRegistrationRepository clientRegistrationRepository,
          ReactiveOAuth2AuthorizedClientService authorizedClientService) {
    
        ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
            ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
                .clientCredentials()
                .build();
    
        AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
            new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
                clientRegistrationRepository, authorizedClientService);
        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
    
        return authorizedClientManager;
      }
    
    
      @Bean
      public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
        return WebClient.builder().filter(oauth).build();
      }