Google api 使用Google管理员目录API使用Google ServiceAccountCredential登录需要401
我尝试了下面列出的简单示例: 不同之处在于我生成了一个服务帐户凭据,并将其分配为具有项目所有者角色的代理,因此它具有完全访问权限。我还为它分配了适当的作用域名称空间 在这里,它可以访问orgunits,这就是我试图在目录API中列出的内容 这是我的服务帐户 这是我的证件 我下载了凭证的JSON并将其添加到我的项目中。我可以通过检查调试器来确认代码加载ServiceAccountCredential并成功地进行身份验证并获取访问令牌 但随后我将凭证传递给服务初始值设定项,当我创建并执行一个请求时,它会失败Google api 使用Google管理员目录API使用Google ServiceAccountCredential登录需要401,google-api,google-oauth,google-admin-sdk,google-api-dotnet-client,google-workspace,Google Api,Google Oauth,Google Admin Sdk,Google Api Dotnet Client,Google Workspace,我尝试了下面列出的简单示例: 不同之处在于我生成了一个服务帐户凭据,并将其分配为具有项目所有者角色的代理,因此它具有完全访问权限。我还为它分配了适当的作用域名称空间 在这里,它可以访问orgunits,这就是我试图在目录API中列出的内容 这是我的服务帐户 这是我的证件 我下载了凭证的JSON并将其添加到我的项目中。我可以通过检查调试器来确认代码加载ServiceAccountCredential并成功地进行身份验证并获取访问令牌 但随后我将凭证传递给服务初始值设定项,当我创建并执行一个请求时,
{"Google.Apis.Requests.RequestError\r\nLogin Required [401]\r\nErrors [\r\n\tMessage[Login Required] Location[Authorization - header] Reason[required] Domain[global]\r\n]\r\n"}
代码如下:
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using System;
using System.Collections.Generic;
using System.IO;
namespace DirectoryQuickstart
{
class Program
{
static string[] Scopes = { DirectoryService.Scope.AdminDirectoryUser, DirectoryService.Scope.AdminDirectoryOrgunit };
static string ApplicationName = "slea-crm";
static string Secret = "gsuite-secret.json";
static void Main(string[] args)
{
ServiceAccountCredential sac = GoogleCredential.FromFile(Secret).CreateScoped(Scopes).UnderlyingCredential as ServiceAccountCredential;
var token = sac.GetAccessTokenForRequestAsync().Result;
// Create Directory API service.
var service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = sac,
ApplicationName = ApplicationName,
});
OrgunitsResource.ListRequest request = service.Orgunits.List(customerId: "REDACTED");
IList<OrgUnit> orgUnits = request.Execute().OrganizationUnits;
if (orgUnits != null && orgUnits.Count > 0)
{
foreach (var orgUnit in orgUnits)
{
Console.WriteLine("{0} ({1})", orgUnit.Name, orgUnit.OrgUnitPath);
}
}
else
{
Console.WriteLine("No orgunits found.");
}
Console.Read();
}
}
}
下面是我的JSON机密的内容和密文
我错过了什么
编辑:好的,我在代码生成请求时中断代码,我可以看到它在头中没有在哪里设置授权令牌承载。为什么?我希望这个HttpClientInitializer类能够解决这个问题,因为API文档说它知道如何处理这个问题,我在internet上找到的每个示例都表明它只是将凭证传递到服务初始值设定项中。但是当我浏览它时,即使凭证已经被授予了访问令牌并且其中存在一个,请求的头也没有更新
我唯一能看到的是,有一种方法可以添加一个HTTP请求拦截器,我可以自己做,但是哇,这看起来真的…奇怪-在他们在dotnet客户端SDK上做了这么多工作之后,老实说,我可以直接编写HTTP API,这样会简单得多,也更容易理解
拼图中缺少的部分是这一行:
ServiceAccountCredential sac = GoogleCredential.FromFile(Secret)
.CreateScoped(Scopes)
.UnderlyingCredential as ServiceAccountCredential;
需要对此进行修改:
static string userName = "admin@yourdomain.com" // valid user in your org
ServiceAccountCredential sac = GoogleCredential.FromFile(Secret)
.CreateScoped(Scopes)
.CreateWithUser(userName)
.UnderlyingCredential as ServiceAccountCredential;
Java/Python/Go做类似事情的示例如下:拼图中缺少的部分是这一行:
ServiceAccountCredential sac = GoogleCredential.FromFile(Secret)
.CreateScoped(Scopes)
.UnderlyingCredential as ServiceAccountCredential;
需要对此进行修改:
static string userName = "admin@yourdomain.com" // valid user in your org
ServiceAccountCredential sac = GoogleCredential.FromFile(Secret)
.CreateScoped(Scopes)
.CreateWithUser(userName)
.UnderlyingCredential as ServiceAccountCredential;
Java/Python/Go类似操作的示例如下:已经回答了这个问题,但在这里添加了更多细节。如果有人想冒充用户使用服务帐户在谷歌硬盘上上传文件。遵循以下步骤 创建服务帐户 为服务帐户启用站点范围的委派 获取服务帐户客户端ID 使用Google管理控制台->管理API启用客户端ID以使用Google驱动器API 使用下面的C代码上传文件
public static DriveService GetService()
{
string[] scopes = new string[] { DriveService.Scope.Drive };
//"SERVICE_ACCOUNT_EMAIL_HERE";
String serviceAccountEmail = "test-417@elated-graph-261115.iam.gserviceaccount.com";
// Scope and user email id which you want to impersonate
var initializer = new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes,
User = "yourEmail@domain.com"
};
//get private key, from .JSON file
var credential = new ServiceAccountCredential(initializer.FromPrivateKey("-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCkHeAicu6uFQn0\n7KUVTjgZ68nQui8+c8NmKW8aW8vhkBIKfdewXFECiUlTMPyI+HXbubsCK5Dl2xBS\nnphLq6YyE0xEQxNFLYHwfUKuzGQ2rV+qObcZ0mLZjCaf+pw3YiRVuU6OtslLJKJH\n-----END PRIVATE KEY-----\n"));
// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "DriveAPI",
});
service.HttpClient.Timeout = TimeSpan.FromMinutes(100);
return service;
}
就这样,我们完成了上面的代码,使用模拟/委派在Google驱动器上使用服务帐户上载文件
参考资料:已回答此问题,但在此添加更多详细信息。如果有人想冒充用户使用服务帐户在谷歌硬盘上上传文件。遵循以下步骤 创建服务帐户 为服务帐户启用站点范围的委派 获取服务帐户客户端ID 使用Google管理控制台->管理API启用客户端ID以使用Google驱动器API 使用下面的C代码上传文件
public static DriveService GetService()
{
string[] scopes = new string[] { DriveService.Scope.Drive };
//"SERVICE_ACCOUNT_EMAIL_HERE";
String serviceAccountEmail = "test-417@elated-graph-261115.iam.gserviceaccount.com";
// Scope and user email id which you want to impersonate
var initializer = new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes,
User = "yourEmail@domain.com"
};
//get private key, from .JSON file
var credential = new ServiceAccountCredential(initializer.FromPrivateKey("-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCkHeAicu6uFQn0\n7KUVTjgZ68nQui8+c8NmKW8aW8vhkBIKfdewXFECiUlTMPyI+HXbubsCK5Dl2xBS\nnphLq6YyE0xEQxNFLYHwfUKuzGQ2rV+qObcZ0mLZjCaf+pw3YiRVuU6OtslLJKJH\n-----END PRIVATE KEY-----\n"));
// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "DriveAPI",
});
service.HttpClient.Timeout = TimeSpan.FromMinutes(100);
return service;
}
就这样,我们完成了上面的代码,使用模拟/委派在Google驱动器上使用服务帐户上载文件
参考资料:你表演了吗?是的,我表演了。请看我刚才在下面发布的答案。伙计,这是一次令人沮丧的尝试。你表演了吗?是的,我表演了。请看我刚才在下面发布的答案。伙计,这是一次令人沮丧的努力。