小编典典

Spring Security 5替换OAuth2RestTemplate

spring-boot

在,和spring-security- oauth2:2.4.0.RELEASE等类中OAuth2RestTemplate,所有这些都已被标记为已弃用。OAuth2ProtectedResourceDetails``ClientCredentialsAccessTokenProvider

从这些类的javadoc中,它指向Spring Security迁移指南,该指南暗示人们应该迁移到核心Spring-security
5项目。但是,我在寻找如何在该项目中实现用例时遇到了麻烦。

如果您希望对应用程序的传入请求进行身份验证并且想要使用第三方OAuth提供程序来验证身份,则所有文档和示例都讨论了与第三部分OAuth提供程序集成的问题。

在我的用例中,我要做的就是RestTemplate向受OAuth保护的外部服务发出请求。目前OAuth2ProtectedResourceDetails,我使用客户ID和密码创建了一个,并将其传递给OAuth2RestTemplate。我还ClientCredentialsAccessTokenProvider向中添加了一个自定义,该自定义OAuth2ResTemplate仅将一些额外的标头添加到我正在使用的OAuth提供程序所需的令牌请求中。

在spring-security 5文档中,我找到了一个部分,该部分提到了自定义令牌请求,但又一次看起来是在与第三方OAuth提供者验证传入请求的上下文中。尚不清楚如何将其与类似的东西结合使用,ClientHttpRequestInterceptor以确保对外部服务的每个传出请求都首先获得令牌,然后再将令牌添加到请求中。

同样,在上面链接的迁移指南中,引用了一个OAuth2AuthorizedClientService,它说对在拦截器中使用很有用,但是这看起来又像是依赖于这样的东西ClientRegistrationRepository,如果您想使用,它似乎在其中维护着第三方提供商的注册。提供以确保对传入请求进行身份验证。

有什么方法可以利用spring-security 5中的新功能来注册OAuth提供程序,以便获得令牌以添加到应用程序的传出请求中?


阅读 1020

收藏
2020-05-30

共1个答案

小编典典

Spring Security 5.2.x的OAuth 2.0客户端功能不支持RestTemplate,仅支持WebClient。参见Spring
Security Reference

HTTP客户端支持

  • WebClient Servlet环境的集成(用于请求受保护的资源)

此外,RestTemplate在以后的版本中将不推荐使用。参见RestTemplate
javadoc

注意: 从5.0开始,无阻塞,无功
org.springframework.web.reactive.client.WebClient提供了的现代替代方案,对RestTemplate同步和异步以及流方案均提供了有效的支持。该RestTemplate会在未来的版本中被淘汰,并没有重大的新功能的加入前进。有关WebClient更多详细信息和示例代码,请参见Spring
Framework参考文档的部分。

因此,最好的办法是放弃RestTemplate赞成WebClient


使用WebClient的客户端凭证流

通过编程或使用Spring Boot自动配置来配置客户端注册和提供程序:

spring:
  security:
    oauth2:
      client:
        registration:
          custom:
            client-id: clientId
            client-secret: clientSecret
            authorization-grant-type: client_credentials
        provider:
          custom:
            token-uri: http://localhost:8081/oauth/token

......和OAuth2AuthorizedClientManager @Bean

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
        ClientRegistrationRepository clientRegistrationRepository,
        OAuth2AuthorizedClientRepository authorizedClientRepository) {

    OAuth2AuthorizedClientProvider authorizedClientProvider =
            OAuth2AuthorizedClientProviderBuilder.builder()
                    .clientCredentials()
                    .build();

    DefaultOAuth2AuthorizedClientManager authorizedClientManager =
            new DefaultOAuth2AuthorizedClientManager(
                    clientRegistrationRepository, authorizedClientRepository);
    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

    return authorizedClientManager;
}

配置WebClient实例以ServerOAuth2AuthorizedClientExchangeFilterFunction与提供的实例一起使用OAuth2AuthorizedClientManager

@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
    ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
            new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
    oauth2Client.setDefaultClientRegistrationId("custom");
    return WebClient.builder()
            .apply(oauth2Client.oauth2Configuration())
            .build();
}

现在,如果您尝试使用此WebClient实例发出请求,它将首先从授权服务器请求令牌,并将其包含在请求中。

2020-05-30