Google Drive API - 从服务帐户转移所有权

问题描述 投票:0回答:3

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

资源主体包括不可直接写入的字段。 [403] 错误 [Message[The resource body includes fields that are not directly writable.] 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";返回以下错误

当权限角色为'owner'时,必须启用transferOwnership参数。 [403]错误[消息[当权限角色为“所有者”时必须启用transferOwnership参数。]位置[transferOwnership - 参数]原因[禁止]域[全局]]

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

[email protected] 电子邮件地址已创建并在 Google Apps 中进行管理。

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

谢谢

c# google-drive-api
3个回答
4
投票

我已经找到答案并发布给遇到这个问题的其他人。

  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. 您需要按照此处列出的步骤将域范围的权限委托给服务帐户。

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

1
投票

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

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

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


0
投票

您实际上可以通过 Google Drive API 将文件或文件夹的所有权从服务帐户的 Google Drive 转移到个人帐户

您必须首先从个人账户(所有者)提出“转让所有权”请求。 可以从所有者的 Google 云端硬盘用户界面屏幕提出此请求。 该消息然后声明收件人必须接受“转让所有权”邀请。但是服务帐户没有 Gmail 的收件箱或 UI 屏幕来执行此操作。 您现在可以使用 Google Drive API 编写一段代码来接受它。

这里是示例 Python 代码

def transfer_ownership(folder_id, SA_email):
        # Define the permission body
        permission = {
            'type': 'user',
            'role': 'owner',
            'emailAddress': SA_email,
        }

        try:
            service.permissions().create(
                fileId = folder_id,
                body = permission,
                transferOwnership = True,
            ).execute()
            print(
                "Ownership of the resource has been transferred to the new Service Account {}".format(
                    SA_email
                )
            )
        except Exception as e:
            err_msg = "An error occurred while transferring the ownership {}".format(str(e))
            raise RuntimeError(err_msg)
© www.soinside.com 2019 - 2024. All rights reserved.