【问题标题】:Spring Boot 2 Spring-Security 5 OAuth2 support for client_credentials grant_typeSpring Boot 2 Spring-Security 5 OAuth2 支持 client_credentials grant_type
【发布时间】:2020-05-26 20:01:24
【问题描述】:

我有一个使用 OIDC/OAuth2 进行身份验证和授权的 Spring Boot 2 应用程序。

我们的目标是有一个 GUI,用户被重定向到授权服务器,以便通过 authentication_code 授权类型登录。

此外,该应用还为其他服务器应用提供 REST Web 服务。服务器到服务器的通信应该由来自同一授权服务器的 client_credentials 授权类型保护。

该应用还需要在无需用户交互的情况下从其他服务器应用访问 REST Web 服务,因此需要具有 client_credentials 授权类型的令牌。

现在我需要在我的应用程序中使用不记名令牌才能访问其他服务器的 Web 服务。 目前,我通过发送 HTTP 请求使用 RestTemplate 检索它:

 private OAuth2AccessToken getBearerToken(ClientRegistration clientRegistration){
    String tokenUri = clientRegistration.getProviderDetails().getTokenUri();

    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
    map.add("grant_type", clientRegistration.getAuthorizationGrantType().getValue());
    map.add("client_id",clientRegistration.getClientId());
    map.add("client_secret",clientRegistration.getClientSecret());

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);

    ResponseEntity<DefaultOAuth2AccessToken> exchange = restTemplate.exchange(tokenUri, HttpMethod.POST, entity, DefaultOAuth2AccessToken.class);
    LOGGER.info(exchange.getBody().getValue());
    return exchange.getBody();
}

现在我在 application.yml 中定义了多个具有不同授权类型的 OAuth2 客户端,并从 ClientRegistrationRepository 中获取了 client_credentials ClientRegistration。但是有没有办法利用 Spring-Security 5 OAuth2 Client 功能为我检索不记名令牌?

我正在尝试以下方法:

 ClientRegistration adfsclient = clientRegistrationRepository.findByRegistrationId("client_credentials");
    OAuth2AuthorizationContext.Builder builder = OAuth2AuthorizationContext.withClientRegistration(adfsclient);
    OAuth2AuthorizationContext build = builder.build();
    OAuth2AuthorizedClient authorize = clientProvider.authorize(build);

但我得到了:

java.lang.IllegalArgumentException: principal cannot be null
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.security.oauth2.client.OAuth2AuthorizationContext$Builder.build(OAuth2AuthorizationContext.java:199) ~[spring-security-oauth2-client-5.2.1.RELEASE.jar:na]
at my.test.sso.adfs.WebAPICaller.callURI(WebAPICaller.java:36) ~[classes/:na]
....
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]

但我没有校长,实际上我也不需要校长。有没有其他方法可以利用 Spring Security OAuth2 Client 来获取不记名令牌?

谢谢,佩罗

【问题讨论】:

    标签: java spring spring-boot access-token spring-security-oauth2


    【解决方案1】:

    我发现 OAuth2RestTemplate 完全符合我的需要。

        @Bean()
        @ConfigurationProperties(prefix ="spring.security.oauth2.client.registration.adfs")
        protected ClientCredentialsResourceDetails oAuthDetails() {
            return new ClientCredentialsResourceDetails();
        }
    
    
    
        @Bean
        public OAuth2RestTemplate oAuth2RestTemplate(ClientCredentialsResourceDetails oAuthDetails){
            return new OAuth2RestTemplate(oAuthDetails);
        }
    

    最终通过调用:

        OAuth2AccessToken accessToken = oAuth2RestTemplate.getAccessToken();
    

    我需要的。

    甚至可以使用 WebClient 实例来获取令牌 描述here

    【讨论】:

      猜你喜欢
      • 2017-11-14
      • 2019-09-17
      • 2018-08-18
      • 2015-08-31
      • 2015-11-27
      • 2020-07-07
      • 2017-09-11
      • 2018-10-04
      • 2021-04-09
      相关资源
      最近更新 更多