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

tim*_*kly 5 c# google-drive-api

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

资源主体包括不可直接写入的字段。[403] 错误 [消息[资源主体包括不可直接写入的字段。] 位置[ - ] 原因[fieldNotWritable] 域[全局]]

        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;
Run Code Online (Sandbox Code Playgroud)

注释掉 // 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 临时创建文档并分配权限和转移所有权。

谢谢

tim*_*kly 5

我已经找到了答案,并正在为遇到这个问题的其他人发帖。

  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
        });
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 您需要按照此处列出的步骤将域范围的权限委派给服务帐户。

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