如何结合 Azure AD 单点登录访问 Google API

How to access Google API in combination with Azure AD single-sign on

我在 Azure 上有一个 Web 应用程序 运行。 Web 应用程序通过来自 Azure Active Directory 租户的 OpenID Connect 对用户进行身份验证。 Azure Sample on GitHub

在 Azure Active Directory 租户上,我集成了 Google 应用程序并配置了单点登录到 Google 应用程序和自动用户配置。 Tutorial: How to integrate Google Apps with Azure Active Directory

在我的网络应用程序中,我想通过 Google API 访问已登录用户的 Google 应用程序(例如 Google 驱动器上的文件)的用户内容.

是否可以在设置单点登录联盟的帮助下做到这一点,这样用户只需要登录到 Web application/Azure AD 和 Web API无需进一步登录,例如通过使用 Azure AD 获得的令牌访问 Google Web API?

从 Azure AD 获得的令牌不能直接用于 Google API。但是,如果您集成了 Azure AD 和 Google 应用程序,您应该能够完成 google 令牌获取过程,而无需再次收集用户凭据。您可能希望通过授权代码流从 google 获取令牌,并注入有助于利用现有会话的请求信息。典型示例是传递用户的 UPN(通过 login_hint 查询参数)和租户 (domain_hint)。但是我不知道 google 授权端点是否会传递这些信息,您需要查阅 google api 文档。

我最终得到了两个解决方案:

a) 服务帐号:
代表用户使用服务帐户访问用户数据。 为此,您必须设置一个服务帐户:Using OAuth 2.0 for Server to Server Applications

private static ServiceAccountCredential GetServiceAccountCredential(string user)
{
  const string privateKey = "<PRIVATEKEY>";

  ServiceAccountCredential credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer("<SERVICEACOUNTEMAIL>")
      {
        Scopes = new[] {DriveService.Scope.Drive},
        User = user
      }.FromPrivateKey(privateKey));

  return credential;
}

b) 用户: 与用户一起访问用户数据。为此,您必须注册您的应用程序以获取客户端 ID 和密码:Using OAuth 2.0 for Web Server Applications

private static UserCredential GetUserCredential(string user)
{
  ClientSecrets secrets = new ClientSecrets
    {
      ClientId = "<CLIENTID>",
      ClientSecret = "<CLIENTSECRET>"
    };

  IDataStore credentialPersistanceStore = new FileDataStore("Drive.Sample.Credentials");

  Task<UserCredential> result = GoogleWebAuthorizationBroker.AuthorizeAsync(
    secrets, 
    new[] {DriveService.Scope.Drive}, 
    user, 
    CancellationToken.None, 
    credentialPersistanceStore);

   result.Wait();
   UserCredential credential = result.Result;

   return credential;
 }

使用凭据,我可以从云端硬盘请求文件:

Claim emailClaim = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email);
IConfigurableHttpClientInitializer credential = GetServiceAccountCredential(emailClaim.Value);
//IConfigurableHttpClientInitializer credential = GetUserCredential(emailClaim.Value);

var service = new DriveService(new BaseClientService.Initializer
  {
    HttpClientInitializer = credential,
    ApplicationName = "My App"
  });

FileList list = service.Files.List().Execute();

我还不确定我会使用哪个选项。也许您有什么意见或建议。