Как я могу использовать client_credentials для доступа к другому ресурсу oauth2 с сервера ресурсов? - PullRequest
0 голосов
/ 28 октября 2019

Я хочу использовать client_credentials для доступа к другому ресурсу, защищенному oauth2, с реактивного сервера ресурсов. Часть, где я обращаюсь к серверу ресурсов с использованием выданного токена, работает, но не вызывает другой ресурс с помощью веб-клиента.

Используя UnAuthenticatedServerOAuth2AuthorizedClientRepository, я получаю serverWebExchange must be null, а используя AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository - principalName must be null.

Использование https://www.baeldung.com/spring-webclient-oauth2 работает так долго, как я вызываю клиента, пока я вызываю клиента 1009. Ни одно из других предложений, которые я нашел здесь о stackoverflow, не сработало.

Что я здесь упускаю? Я использую Spring Security 5.2.0 и Spring Boot 2.2.0.

ClientConfig:

@Configuration
public class ClientSecurityConfig {

    // UnAuthenticatedServerOAuth2AuthorizedClientRepository version

    @Bean
    WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
                new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());

        return WebClient.builder()
                .filter(oauth)
                .build();
    }

    @Bean
    ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider(CustomClientConfig clientConfig) {
        return ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
                        .clientCredentials(clientCredentialsGrantBuilder ->
                                clientCredentialsGrantBuilder.accessTokenResponseClient(new CustomClient(clientConfig))) // Used to send extra parameters to adfs server
                        .build();
    }


    // AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository version

    @Bean
    WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
                new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
        return WebClient.builder()
                .filter(oauth)
                .build();
    }
}

    @Bean
    ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
            ReactiveClientRegistrationRepository clientRegistrationRepository,
            ServerOAuth2AuthorizedClientRepository authorizedClientRepository, CustomClientConfig clientConfig) {

        ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
                ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
                        .clientCredentials(clientCredentialsGrantBuilder ->
                                clientCredentialsGrantBuilder.accessTokenResponseClient(new CustomClient(clientConfig))) // Used to send extra parameters to adfs server
                        .build();
        DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager =
                new DefaultReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

        return authorizedClientManager;
    }
}

ResourceServerConfig:

@EnableWebFluxSecurity
class ResourceServerConfig {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
                .authorizeExchange(exchanges ->
                        exchanges
                                .pathMatchers("/actuators/**", "/api/v1").permitAll()
                                .pathMatchers("/api/v1/**").hasAuthority("SCOPE_read")
                                .anyExchange().authenticated()
                )
                .formLogin().disable()
                .httpBasic().disable()
                .oauth2Client(withDefaults())
                .oauth2ResourceServer().jwt();
        return http.build();
    }
    @RestController()
    @RequestMapping("/api/v1")
    static class Ctrl {
        final static Logger logger = LoggerFactory.getLogger(Ctrl.class);
        final WebClient webClient;

        public Ctrl(WebClient webClient) {
            this.webClient = webClient;
        }

        @RequestMapping("protected")
        Mono<JsonNode> protected(@RequestParam String data) {
            return webClient.post()
                    .uri("https://other-oauth2-protected-resource")
                    .attributes(clientRegistrationId("myclient"))
                    .bodyValue("{\"data\": \"" + data + "\"}")
                    .retrieve()
                    .bodyToMono(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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...