【问题标题】:Calling Youtube API with Spring Security OAuth Principal使用 Spring Security OAuth Principal 调用 Youtube API
【发布时间】:2021-01-25 23:20:48
【问题描述】:

我在玩弄 Google YouTube API Java 客户端库。我编写了一个 Spring Boot 服务,您可以使用 Spring Security OAuth 使用您的 Google 帐户登录。这一切都很好。

现在,在 REST 端点方法中,我有类似的东西

@RequestMapping(value="/thing")
public ChannelListResponse getAThing( Principal principal )
{ ... }

其中Principal 实例是OAuth2AuthenticationToken 的一个实例。

理想情况下,我希望我的服务使用登录用户的凭据进行 YouTube API 调用,但我无法弄清楚如何从给定的 Principle 实例构建 GoogleCredentials 实例。

我知道我可以从我的 API 密钥文件中创建一个 ServiceAccountCredentials,事实上我可以使用它,但我很好奇是否可以使用 OAuth2AuthenticationToken(我的 Principal)来制作代表该证书致电。我实际上想在用户和 Google 之间插入并能够增强/装饰其他数据,并且理想情况下使用用户的凭据完成所有操作。

感谢您的见解。

【问题讨论】:

    标签: spring-boot spring-security google-oauth youtube-data-api spring-security-oauth2


    【解决方案1】:

    根据the official docs,要构建GoogleCredential 实例,您必须拥有一个有效的访问令牌,并且必须像这样进行:

    TokenResponse tokenResponse = new TokenResponse();
    tokenResponse.setAccessToken(accessToken);
    
    Credential credential = 
        createCredentialWithAccessTokenOnly(tokenResponse);
    

    地点:

    public static GoogleCredential
        createCredentialWithAccessTokenOnly(
            TokenResponse tokenResponse)
    {
        return new GoogleCredential().
            setFromTokenResponse(tokenResponse);
    }
    

    根据a tutorial already quoted on SO,所需的访问令牌可从您的OAuth2AuthenticationToken 实例获得,如下所示:

    OAuth2AuthorizedClientService clientService;
    OAuth2AuthenticationToken oauthToken;
    
    OAuth2AuthorizedClient client =
        clientService.loadAuthorizedClient(
            oauthToken.getAuthorizedClientRegistrationId(),
            oauthToken.getName());
    
    String accessToken = 
        client.getAccessToken().getTokenValue();
    

    另外,您可以follow this doc查看如何获取上述OAuth2AuthorizedClientService的实例。

    附录

    如果想脱离我上面提到的已弃用的GoogleCredential 类并改用GoogleCredentials 类,那么事情似乎更简单:

    public static GoogleCredentials
        createCredentialsWithAccessTokenOnly(
             OAuth2AccessToken oauthAccessToken)
    {
        AccessToken accessToken = new AccessToken(
            oauthAccessToken.getTokenValue(),
            Date.from(oauthAccessToken.getExpiresAt()));
        return GoogleCredentials.create(accessToken);
    }
    

    (不再需要使用TokenResponse)。

    对于将作用域附加到 GoogleCredentials 类的问题,我认为这是不必要的。

    请注意,任何给定的有效访问令牌本身(已经!)都附加了一组范围。该集合是在 OAuth 流程期间指定的。例如,您可以调用以下 URL(例如在浏览器中,或通过在命令行提示符处发出 wgetcurl):

    https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ACCESS_TOKEN,

    用具体的访问令牌替换ACCESS_TOKEN,以查看附加到相应令牌的范围。

    通过这种 HTTPS GET 方法调用获得的 JSON 响应如下所示:

    {
      "issued_to": "...",
      "audience": "...",
      "scope": "...",
      "expires_in": 3599,
      "access_type": "offline"
    }
    

    【讨论】:

    • 谢谢@stvar。这让我更接近。我可以使用您的建议创建 GoogleCredential。 GoogleCredential 现在已弃用,我可能应该弄清楚如何使用较新的 GoogleCredentials 类层次结构来做到这一点。此外,我需要为要调用的 API 指定身份验证范围,而 GoogleCredential 基类不支持该范围。但我认为您基本上已经回答了我关于如何使用委托人进行身份验证的基本问题。再次感谢您!
    • 我希望createCredentialsWithAccessTokenOnly 现在可以了。 (目前无法测试。)
    猜你喜欢
    • 2020-12-02
    • 2018-09-30
    • 2020-01-15
    • 2017-06-28
    • 2017-01-07
    • 2014-08-07
    • 2018-01-24
    • 2015-03-11
    • 2020-09-05
    相关资源
    最近更新 更多