【问题标题】:Google Drive API - Transfer ownership from Service AccountGoogle Drive API - 从服务帐户转移所有权
【发布时间】:2016-08-15 08:11:39
【问题描述】:

我正在尝试使用以下代码将所有权从服务帐户创建的文档转移给位于同一 Google Apps 帐户中的另一个用户,但出现以下错误

资源主体包含不可直接写入的字段。 [403] 错误 [消息[资源正文包含不可直接写入的字段。] Location[ - ] Reason[fieldNotWritable] Domain[global]]

        var service = GetService();

        try
        {
            var permission = GetPermission(fileId, email);
            permission.Role = "owner";

            var updatePermission = service.Permissions.Update(permission, fileId, permission.Id);
            updatePermission.TransferOwnership = true;
            return updatePermission.Execute();
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: " + e.Message);
        }
        return null;

注释掉 // permission.Role = "owner";返回下面的错误

当权限角色为“所有者”时,必须启用 transferOwnership 参数。 [403] 错误 [消息[当权限角色为“所有者”时,必须启用 transferOwnership 参数。] Location[transferOwnership - parameter] Reason[forbidden] Domain[global]]

分配任何其他权限都可以正常工作。因此,这是服务帐户无法将所有权转移到不使用@gserviceaccount.com 电子邮件地址的任何其他帐户的限制(即 our-project@appspot.gserviceaccount.com > email@domain.com) ?

email@domain.com 电子邮件地址已创建并在 Google Apps 中进行管理。

在这种情况下,这是无法实现的,关于下一步该去哪里的任何指示?我们需要多个用户能够通过 API 即时创建文档并分配权限和转移所有权。

谢谢

【问题讨论】:

  • 感谢@DalmTo,但我使用的是 V3 API,更新功能是来自 V2 Migrate to Google Drive API v3 的旧补丁功能。
  • 好吧,你的代码很难判断它是 v2 还是 v3。补丁在 V2 中工作。权限对于 Google 云端硬盘来说是一件很痛苦的事情。
  • 如您所说,您可以使用 ServiceAccountCredential.Initializer 方法对具有 Drive 服务权限和数据传输权限的 impersonate a user。这反过来将委派对服务帐户的域范围访问。请参阅this 代码实现。希望这会有所帮助!

标签: c# google-drive-api


【解决方案1】:

我找到了答案,并为遇到此问题的其他人发帖。

  1. 您不能使用 Google 推荐的“服务帐户密钥 JSON 文件”。
  2. 您需要使用 p.12 证书文件进行身份验证。
  3. 创建模拟账户驱动服务的代码如下。

    public DriveService GetService(string certificatePath, string certificatePassword, string googleAppsEmailAccount, string emailAccountToMimic, bool allowWrite = true)
    {
        var certificate = new X509Certificate2(certificatePath, certificatePassword, X509KeyStorageFlags.Exportable);
    
        var credential = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(googleAppsEmailAccount)
           {
               Scopes = new[] { allowWrite ? DriveService.Scope.Drive : DriveService.Scope.DriveReadonly },
               User = emailAccountToMimic
           }.FromCertificate(certificate));
    
        // Create the service.
        return new DriveService(new BaseClientService.Initializer
        {
            HttpClientInitializer = credential,
            ApplicationName = ApplicationName
        });
    }
    
  4. 您需要按照here 列出的步骤将域范围的权限委派给服务帐户。

  5. 完成第 4 步后等待 5 到 10 分钟。
  6. 您现在可以在“emailAccountToMimic”用户下创建文档,该用户在创建过程中将其设置为所有者。

【讨论】:

  • 仅供参考 - 原来您需要使用 emailAccountToMimic 帐户创建文档,然后将“写入者”权限分配给可以写入文档的服务帐户的文档。
【解决方案2】:

我认为不可能将所有权从非 ServiceAccount 转移到 ServiceAccount,反之亦然。

如果您以交互方式执行此操作,您将收到以下错误:

通常,文档可以由用户创建和拥有,并且可以使用他们自己的凭据完成所有权转移。如果您的服务帐户被正确授予域范围的委派,您还可以选择冒充所有者。

【讨论】:

  • 谢谢@some1。我实际上是在尝试将 ServiceAccount 中的权限分配给非 ServiceAccount,并且我已经为服务帐户设置了域范围的委派并按照 here 的说明分配了权限,但我使用的是服务帐户密钥 JSON 文件(如Google 推荐),它具有与 OAuth 2.0 身份验证不同的初始化程序,而 OAuth 2.0 身份验证依赖于证书......但它也允许在使用 ServiceAccountCredential.Initializer 方法时进行帐户模拟。
猜你喜欢
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 2012-10-20
相关资源
最近更新 更多