本文介绍了Spring Boot授权服务器+Google OAuth2/OpenID Connect应该与Access_Token或id_Token一起工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道应该通过Access_Token还是id_Token访问我的Spring Boot资源服务器。

首先,让我快速解释一下我的设置:

  • 作为OAuth 2.0 Resource Server的Spring Boot应用程序。这是按照Spring文档中所述进行配置的:Minimal Configuration for JWTs这个应用程序提供了安全的@控制器,这些控制器将为一个JavaScript SPA(例如.反应)
  • Google的OAuth 2.0 AP / OpenID Connect已配置(凭据、客户端ID、客户端密码)
  • 一款JavaScript SPA应用程序(例如Reaction),它将用户登录到Google,并向Spring Boot资源服务器请求安全数据。这些请求包括登录用户的授权标头(带有从Google获得的持有者令牌)。
  • 出于开发目的,我还使用Postman向Spring Boot资源服务器发出请求

我可以轻松地将Postman配置为从Google获取令牌。来自Google的此令牌响应包括access_tokenid_tokenscopeexpries_intoken_type的值。

但是,当邮递员尝试使用检索到的令牌的access_token字段中的值作为授权标头中的承载时,我对资源服务器的请求被拒绝

我能够成功访问安全@Controllers的唯一方法是使用id_token作为授权标头中的持有者。

是否应该使用id_token作为授权标头中的持有者?还是应该使用access_token

其他相关信息:

  • id_token的值是JWT标记。access_token的值不是JWT标记。我知道这一点是因为我可以解码jwt.io上的id_token,但它无法解码access_token的值。此外,当我将access_token作为授权标头中的持有者发送时,Spring Boot资源服务器失败,出现以下错误:
  • 查看使用OAuth2资源服务器的spring-security-samples,我看到硬编码的access_token的值(出于测试目的)确实是有效的JWT。而不是从不是JWT的Google返回的access_token

小结:

  • 我可以使用从Google获得的id_token的值访问我的Spring Boot资源服务器。access_token的值不是JWT,无法通过Spring Boot进行分析。
  • 是我的理解、我的配置有问题还是什么?关于access_token的工作方式,Google的OpenID Connect的行为是否有所不同?

如果需要,很乐意澄清或添加更多信息。感谢您的考虑和耐心!

推荐答案

您提到的博客文章在我看来是正确的,我相信OpenID Connect1.0规范并不打算将id_token用于访问目的。

像您一样,我希望使用Google作为授权服务器可以开箱即用,因为Spring Security与Google作为一个公共的OAuth2提供者一起工作,以提供社交登录。然而,情况并非如此,我相信这并不是真正的意图,因为谷歌并不是你的授权服务器。例如,我不相信您可以将Google配置为使用您的域特定应用程序的作用域/权限/授权。这不同于Okta,后者有许多选项可以在您自己的租户中配置内容。

我实际上建议您查看Spring Authorization Server,并将Google配置为联合身份提供商。我目前正在制作一个样本,将在下周左右发布(请参阅this branch)。

话虽如此,如果您仍然对使用Google访问令牌进行资源服务器身份验证的简单用例感兴趣,则需要提供使用Google的tokeninfo endpoint的您自己的opaque token introspector。它与Spring Security所期望的不符,因此有点牵涉其中。

@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .authorizeRequests((authorizeRequests) -> authorizeRequests
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken);
        // @formatter:on

        return http.build();
    }

    @Bean
    public OpaqueTokenIntrospector introspector() {
        return new GoogleTokenIntrospector("https://oauth2.googleapis.com/tokeninfo");
    }

}
public final class GoogleTokenIntrospector implements OpaqueTokenIntrospector {
    private final RestTemplate restTemplate = new RestTemplate();
    private final String introspectionUri;

    public GoogleTokenIntrospector(String introspectionUri) {
        this.introspectionUri = introspectionUri;
    }

    @Override
    public OAuth2AuthenticatedPrincipal introspect(String token) {
        RequestEntity<?> requestEntity = buildRequest(token);
        try {
            ResponseEntity<Map<String, Object>> responseEntity = this.restTemplate.exchange(requestEntity, new ParameterizedTypeReference<>() {});
            // TODO: Create and return OAuth2IntrospectionAuthenticatedPrincipal based on response...
        } catch (Exception ex) {
            throw new BadOpaqueTokenException(ex.getMessage(), ex);
        }
    }

    private RequestEntity<?> buildRequest(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("access_token", token);

        return new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(introspectionUri));
    }
}
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://accounts.google.com
          jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs

这篇关于Spring Boot授权服务器+Google OAuth2/OpenID Connect应该与Access_Token或id_Token一起工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 14:10