使用PowerShell调用Google API获取SAML日志遇权限拒绝问题求助
问题
执行PowerShell脚本通过Google API获取所有SAML日志时,调用GET请求遇到错误:
"Access denied. You are not authorized to read activity records."
已执行的操作:
- 创建Google Cloud Platform项目并启用「Admin SDK API」
- 创建服务账号并下载JSON格式密钥
- 在Google管理控制台的全域委派配置中,将服务账号的客户端ID与
https://www.googleapis.com/auth/admin.reports.audit.readonly范围进行注册 - 使用凭据(JSON文件)创建证书和JWT令牌
- 获取访问令牌并执行GET请求
用户提供的PowerShell代码:
$cert = Get-PfxCertificate -FilePath "./cer.pfx" -Password (ConvertTo-SecureString "..." -AsPlainText -Force) # The service account credentials $now = (Get-Date).ToUniversalTime() $createDate = [Math]::Floor([decimal](Get-Date($now) -UFormat "%s")) $expiryDate = [Math]::Floor([decimal](Get-Date($now.AddHours(1)) -UFormat "%s")) $rawclaims = [Ordered]@{ iss = "test@test.iam.gserviceaccount.com" # Your service account scope = "https://www.googleapis.com/auth/admin.reports.audit.readonly" aud = "https://accounts.google.com/o/oauth2/token" sub = "test@test.iam.gserviceaccount.com" iat = $createDate exp = $expiryDate } | ConvertTo-Json # Encoding the JWT claim set $jwt = New-Jwt -PayloadJson $rawclaims -Cert $cert #-Verbose # Making the access token request $apiendpoint = "https://oauth2.googleapis.com/token" $splat = @{ Method = "POST" Uri = $apiendpoint ContentType = "application/x-www-form-urlencoded" Body = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$jwt" } # Get access token to authenticate with SPN try { $res = Invoke-RestMethod @splat -Verbose } catch { [Console]::Error.WriteLine("Error during GCP authentication : $_") } # Get SAML logs $headers = @{ "Authorization" = "Bearer $($res.access_token)" } $uri = "https://www.googleapis.com/admin/reports/v1/activity/users/all/applications/saml" $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers $response
解决方案
核心问题修正
sub字段配置错误是导致权限拒绝的主要原因:
服务账号本身没有Google Workspace域的权限,必须模拟域内具有管理员权限的用户才能访问Reports API。因此需要将rawclaims中的sub值改为域内管理员邮箱(比如admin@yourdomain.com),而非服务账号邮箱。
修正后的rawclaims部分:
$rawclaims = [Ordered]@{ iss = "test@test.iam.gserviceaccount.com" # 服务账号邮箱 scope = "https://www.googleapis.com/auth/admin.reports.audit.readonly" aud = "https://accounts.google.com/o/oauth2/token" sub = "admin@yourdomain.com" # 替换为你的域管理员邮箱 iat = $createDate exp = $expiryDate } | ConvertTo-Json
额外验证步骤
- 确认全域委派状态:
进入Google管理控制台「安全 > API控制 > 域宽委派」,检查服务账号的客户端ID对应的权限范围是否包含https://www.googleapis.com/auth/admin.reports.audit.readonly,且状态为「已授权」。 - 验证管理员权限:
确保sub指定的域用户拥有「查看报表」的管理员权限(在Google管理控制台「管理员角色」中,为该用户分配包含「报表查看器」权限的角色)。 - 检查API启用状态:
再次确认GCP项目中「Admin SDK API」已启用,可在GCP控制台「API和服务 > 已启用的API和服务」中查看。
内容的提问来源于stack exchange,提问作者harris93
相关产品推荐
相关产品推荐

