如何像在 RestTemplate 中一样从 WebClient 获取访问令牌?

Posted

技术标签:

【中文标题】如何像在 RestTemplate 中一样从 WebClient 获取访问令牌?【英文标题】:How to get accesstoken from WebClient like in RestTemplate? 【发布时间】:2021-10-17 16:18:17 【问题描述】:

我正在通过 Spring Security Oauth 2.x 迁移到 Spring security 5.2 并遇到以下阻止程序。 正如我所见,OAuth2RestTemplate 不再使用,而是推荐使用WebClient。所以我正在对我的代码库进行更改以使 webclient 工作。

在 Oauth2 中,我们可以选择使用 oAuth2RestTemplate.getAccessToken() 直接从 RestTemplate 获取令牌,我在 WebClient 中找不到类似的东西。这是调用外部微服务。 是否有任何选项可以从 webclient 获取访问令牌?还是在那里以不同的方式处理?

【问题讨论】:

【参考方案1】:

像往常一样,在使用 Spring Security 时,很多事情都是按照惯例通过配置自动发生的。含义:您应该熟悉与oauth相关的spring安全配置。

spring security docu 或有关该主题的许多优秀 Baeldung 文章之一是您学习的良好起点(也许这篇文章会有所帮助:https://www.baeldung.com/spring-oauth-login-webflux)。

使用正确的配置,以下方法将创建一个WebClient,该WebClient 具有在过滤器方法中按需自动创建的正确oauth 令牌。

在这种情况下,ReactiveOAuth2AuthorizedClientManager 类型的 Bean 会处理这个问题。该 bean 是在清单编号中创建的。 2.

此外,您需要配置 oauth 服务器 url 和凭据。有关简单示例,请参见清单 3。

此示例无需您处理访问令牌即可运行。


    @Bean
    public WebClient oauthWebClient(
        final WebClient.Builder webClientBuilder,
        @Qualifier("authorizedClientManager") final ReactiveOAuth2AuthorizedClientManager manager) 
        final ExchangeStrategies exchangeStrategies =
            ExchangeStrategies.builder()
                              .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(EXCHANGE_BYTE_COUNT))
                              .build();
        final ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(manager);
        oauth.setDefaultClientRegistrationId(authenticationProperties.getClientId());
        // set more properties if needed
        // oauth.set ...

        return webClientBuilder
            .exchangeStrategies(exchangeStrategies)
            .baseUrl(apiProperties.getBaseUrl())
            .filter(oauth)
            .build();
    

清单 1:创建一个 WebClient bean

    @Bean
    public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
        final ReactiveClientRegistrationRepository clientRegistrationRepository,
        final ReactiveOAuth2AuthorizedClientService authorizedClientService) 
        final ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
            ReactiveOAuth2AuthorizedClientProviderBuilder
                .builder()
                .clientCredentials()
                .build();
        final AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
            new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService);
        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
        return authorizedClientManager;
    

清单 2:创建 OAuth2 授权的客户端管理器 bean

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://your-oauth-server.com/auth/realms/your-realm
      client:
        provider:
          your-provider:
            issuer-uri: https://your-oauth-server.com/auth/realms/your-realm
        registration:
          your-provider:
            client-id: your-client-id
            client-secret: $your_client_secret # from an environment variable
            scope: openid
            authorization-grant-type: client_credentials

清单 3:配置 Spring Web 客户端的多种可能方法之一

【讨论】:

以上是关于如何像在 RestTemplate 中一样从 WebClient 获取访问令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何像在 Evernote 应用程序中一样从 iPad 屏幕底部显示 UIView

如何像在 Excel 中一样在 MySQL 中“填充系列”(线性步长值)?

如何在 Android 中像在 Google 地图中一样获得持续的位置更新?

我如何使用 s & $ 访问 Pyspark 中的变量,就像在 Scala 中一样

如何像在 Eclipse 中一样在 IntelliJ 中创建可运行的 JAR

如何像在 Eclipse 中一样在 IntelliJ 中创建可运行的 JAR