Клиент Spring Boot Oauth2 (реактивный) Взаимный токен TLS/SSL uri

Spring boot 2.3.x и Spring 5.x недавно добавили поддержку для настройки реактивного клиента oauth2 на основе класса WebClient.

У меня было требование для конфигурации потока предоставления учетных данных клиента

Выполнение этого вызова без взаимного TLS/SSL не вызывает затруднений.

Обычная (без TLS/SSL) конфигурация (@Configuration) фрагмент кода выглядит следующим образом:-

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

    ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
            .clientCredentials()
            .build();

    DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);

    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
    return authorizedClientManager;
}

@Bean("testClient")
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager,
                           @Value("${test.client.base.url}") String baseUrl) {
    ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFunction = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
    oauthFunction.setDefaultClientRegistrationId("local");
    return WebClient.builder()
            .baseUrl(baseUrl)
            .filter(oauthFunction)
            .build();
}

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.oauth2Client();
    return http.build();
}

Файл свойств

spring.security.oauth2.client.registration.local.authorization-grant-type=client_credentials
spring.security.oauth2.client.registration.local.client-id=client_id
spring.security.oauth2.client.registration.local.client-secret=client_secret

spring.security.oauth2.client.provider.local.token-uri=http://hostname:port/oauth/token
test.client.base.url=http://protected-resource/v1/apis

Но вызов сервера авторизации oauth2 через Mutual TLS(клиентский сертификат) был большим делом.

Как это сделать? Я хотел бы поделиться тем же с сообществом и сам отвечал бы то же самое ниже

1 ответ

Решение

Ответ на требование и главное изменение будет в bean authorizedClientManager

Объем ответа - это поток предоставления учетных данных клиента, хотя изменения для других потоков предоставления oauth2 должны быть аналогичными, и это тоже поможет.

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

    // construct client credential token response client yourself
    WebClientReactiveClientCredentialsTokenResponseClient accessTokenResponseClient = new WebClientReactiveClientCredentialsTokenResponseClient();

    // construct the sslContext as per your needs and inject in below
    // and create httpClient by injecting your sslContext here
    HttpClient httpClient = HttpClient.create()
            .tcpConfiguration(client -> client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000))
            .secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));

    ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);

    accessTokenResponseClient.setWebClient(WebClient.builder().clientConnector(httpConnector).build());

    ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder
            .builder()
            .clientCredentials(c -> {
                c.accessTokenResponseClient(accessTokenResponseClient);
            }).build();

    DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);

    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
    return authorizedClientManager;
}

Здесь, если вы видите линию .secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));

Вам нужно создать sslContext и ввести то же самое, и это будет полностью зависеть от настройки вашего кода.

Подробный код и инструкции вы можете найти по ссылке здесь

Другие вопросы по тегам