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

已授权全域委派的服务账号在Cloud Function调用Admin SDK时遇403错误

问题:配置Google Workspace全域委派的服务账号调用Admin SDK时触发403权限错误

问题描述

配置了Google Workspace全域委派的服务账号,在GCP Cloud Function中调用已授权范围的Admin SDK时,持续收到「Not Authorized to access this resource/api」403权限错误。

环境与配置

  • Cloud Function配置:
    Service account: my-domain-wide-delegation-enabled-serviceaccount@my-gcp-project-name.iam.gserviceaccount.com
    Build service account: my-project-default-service-account@appspot.gserviceaccount.com
    
  • 已在Google Workspace的「Security > API Controls > Domain-wide Delegation」中,为该服务账号的OAuth 2 Client ID授权以下范围:
    https://www.googleapis.com/auth/admin.directory.user
    https://www.googleapis.com/auth/admin.directory.group
    https://www.googleapis.com/auth/gmail.send
    
  • Cloud Function核心代码:
    辅助函数获取Workspace凭证:
    const SCOPES = [
      'https://www.googleapis.com/auth/admin.directory.user',
      'https://www.googleapis.com/auth/admin.directory.group',
      'https://www.googleapis.com/auth/gmail.send'
    ];
    
    async function getWorkspaceCredentials() {
        try {
            console.log("获取Workspace凭证...");
            const auth = new google.auth.GoogleAuth({
            scopes: SCOPES
            });
       
            // 获取源凭证
            console.log("获取客户端...");
            const client = await auth.getClient();
            console.debug("客户端信息: ", {
                email: client.email,  // 服务账号邮箱
                scopes: client.scopes // 实际使用的范围
            });
    
            const email = await auth.getCredentials();
            console.debug("服务账号详情: ", {
                email: email.client_email,
                project_id: email.project_id,
                type: email.type
            });
    
            console.log("设置客户端主体(要模拟的管理员用户)...")
            client.subject = 'testadminaccount@mydomain.com';
    
            const token = await client.getAccessToken();
            console.debug("成功获取测试访问令牌: ", token.token.substring(0,10) + "...");
    
            console.log("Workspace凭证获取成功。");
            return client;
      } catch (error) {
            console.error('获取Workspace凭证失败:', error);
            throw error;
      }
    }
    
    入口函数调用Admin SDK:
    functions.http('createNewWorkspaceAccount', async (req, res) => {
        // 获取Workspace凭证并创建Admin服务
        const auth = await getWorkspaceCredentials();
        console.debug("auth凭证: ", auth);
        const admin = google.admin({ version: 'directory_v1', auth });
        console.debug("基于auth凭证创建的Admin服务: ", admin);
        // 调试测试
        const testList = await admin.users.list({
            domain: 'mydomain.com',
            maxResults: 1
        });
        console.debug("测试列表响应: ", testList.data);
        console.debug("查询已知测试用户的Admin数据: ", await admin.users.get({userKey: "testuser@mydomain.com"}));
    });
    

错误详情

执行到admin.users.list()时触发403错误,完整错误信息:

GaxiosError: Not Authorized to access this resource/api
    at Gaxios._request (/workspace/node_modules/googleapis-common/node_modules/gaxios/build/src/gaxios.js:129:23)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Compute.requestAsync (/workspace/node_modules/googleapis-common/node_modules/google-auth-library/build/src/auth/oauth2client.js:368:18)
    at async /workspace/index.js:236:22 {
  response: {
    config: {
      url: 'https://admin.googleapis.com/admin/directory/v1/users?domain=mydomain.com&maxResults=1',
      method: 'GET',
      userAgentDirectives: [Array],
      paramsSerializer: [Function (anonymous)],
      headers: [Object],
      params: [Object],
      validateStatus: [Function (anonymous)],
      retry: true,
      responseType: 'json',
      retryConfig: [Object]
    },
    data: { error: [Object] },
    headers: {
      'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
      'content-encoding': 'gzip',
      'content-type': 'application/json; charset=UTF-8',
      date: 'Tue, 14 Jan 2025 21:28:50 GMT',
      server: 'ESF',
      'transfer-encoding': 'chunked',
      vary: 'Origin, X-Origin, Referer',
      'x-content-type-options': 'nosniff',
      'x-frame-options': 'SAMEORIGIN',
      'x-xss-protection': '0'
    },
    status: 403,
    statusText: 'Forbidden',
    request: {
      responseURL: 'https://admin.googleapis.com/admin/directory/v1/users?domain=mydomain.com&maxResults=1'
    }
  },
  config: {
    url: 'https://admin.googleapis.com/admin/directory/v1/users?domain=mydomain.com&maxResults=1',
    method: 'GET',
    userAgentDirectives: [ [Object] ],
    paramsSerializer: [Function (anonymous)],
    headers: {
      'x-goog-api-client': 'gdcl/5.1.0 gl-node/20.18.1 auth/7.14.1',
      'Accept-Encoding': 'gzip',
      'User-Agent': 'google-api-nodejs-client/5.1.0 (gzip)',
      Authorization: 'Bearer qwertyqwertyqwerty',
      Accept: 'application/json'
    },
    params: { domain: 'mydomain.com', maxResults: 1 },
    validateStatus: [Function (anonymous)],
    retry: true,
    responseType: 'json',
    retryConfig: {
      currentRetryAttempt: 0,
      retry: 3,
      httpMethodsToRetry: [Array],
      noResponseRetries: 2,
      statusCodesToRetry: [Array]
    }
  },
  code: 403,
  errors: [
    {
      message: 'Not Authorized to access this resource/api',
      domain: 'global',
      reason: 'forbidden'
    }
  ]
}

已排查事项

  • 确认GCP中服务账号的OAuth 2 Client ID与Workspace全域委派中的ID一致
  • 验证testadminaccount@mydomain.com为超级管理员,具备Workspace用户管理权限
  • 尝试重新添加全域委派权限、为服务账号赋予GCP项目Owner角色,均未解决问题
  • 已启用Admin SDK API

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:37:33