You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Google Drive API上传文件遇iam.serviceAccounts.getAccessToken权限拒绝问题

问题:使用Google Drive API(C# SDK)服务账号上传时遇到权限错误“iam.serviceAccounts.getAccessToken”被拒绝

我尝试用Google Drive API的C# SDK上传文件,因为是后台服务,所以用服务账号执行上传,但碰到错误:Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist)。

我已经给项目配置了以下角色:

  • Service Account Token Creator
  • Service Account User
  • 包含iam.serviceAccounts.getAccessToken权限的自定义角色

生成本地JSON凭证的命令

gcloud auth application-default login --project=myprojectid --impersonate-service-account <svcacctname>@<application id>.iam.gserviceaccount.com --scopes="openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/sqlservice.login,https://www.googleapis.com/auth/drive

简化后的C#上传代码

using (var stream =
            new FileStream(@"C:\Users\myname\AppData\Roaming\gcloud\application_default_credentials.json", FileMode.Open, FileAccess.Read))
    {
        var credentials = GoogleCredential.FromStream(stream);
        if (credentials.IsCreateScopedRequired)
        {
            credentials = credentials.CreateScoped(new string[] { DriveService.Scope.Drive });
        }


        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credentials,
            ApplicationName = "myappid",
        });

        FilesResource.CreateMediaUpload request;
        // Create a new file on drive.
        using (var stream = new FileStream(localFileName,
                    FileMode.Open))
        {
            // Create a new file, with metadata and stream.
            request = service.Files.Create(
                fileMetadata, stream, "audio/mp3");
            request.Fields = "id";
            IUploadProgress prog = request.Upload();

            if (prog.Exception != null)
            {
                // code arrives here
                Console.WriteLine(prog.Exception.Message);
            }
            else
            {
                Console.WriteLine(request.ResponseBody);
            }

    }

异常响应

Error:"{
  "error": {
    "code": 403,
    "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
    "errors": [
      {
        "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "IAM_PERMISSION_DENIED",
        "domain": "iam.googleapis.com",
        "metadata": {
          "permission": "iam.serviceAccounts.getAccessToken"
        }
      }
    ]
  }
}
", Description:"", Uri:""
解决方案

1. 修正权限授予对象

iam.serviceAccounts.getAccessToken权限需要授予给执行gcloud命令的用户账号,而非服务账号本身。具体操作:

  • 进入Google Cloud控制台的IAM & Admin > IAM页面
  • 找到你用来登录gcloud的用户账号
  • 点击编辑,添加角色 > Service Accounts > Service Account Token Creator,并将角色作用域指定为目标服务账号(而非整个项目)

2. 修复gcloud命令语法错误

原命令末尾缺少闭合双引号,导致作用域参数不完整,修正后的命令:

gcloud auth application-default login --project=myprojectid --impersonate-service-account <svcacctname>@<application id>.iam.gserviceaccount.com --scopes="openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/sqlservice.login,https://www.googleapis.com/auth/drive"

3. 确认Drive API配置

  • 检查项目是否已启用Google Drive API:进入APIs & Services > Library搜索并启用
  • 若上传到共享文件夹,需将服务账号邮箱添加为文件夹共享成员,授予编辑权限

4. 验证凭证有效性

重新生成凭证后,执行以下命令验证是否能获取有效令牌:

gcloud auth application-default print-access-token --impersonate-service-account <svcacctname>@<application id>.iam.gserviceaccount.com

返回有效令牌则说明凭证配置正确,仍报错则回到步骤1检查权限。

内容的提问来源于stack exchange,提问作者Mike Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 18:53:16