Google API提示‘请求身份验证作用域不足’错误的排查解决
问题背景
我正在开发第一个调用Google API的C#/Windows应用,原本以为已在服务器上配置好所有权限,但运行时抛出Google.GoogleApiException异常。我希望Google API文档能明确标注“该方法需要X、Y、Z作用域授权”,但未能找到相关说明。当前需求是读取已创建的邮件组名称,后续计划读取组成员并更新列表,目前先实现读取组名称即可。
初始异常信息
{ "error": { "code": 403, "message": "Request had insufficient authentication scopes.", "errors": [ { "message": "Insufficient Permission", "domain": "global", "reason": "insufficientPermissions" } ], "status": "PERMISSION_DENIED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT", "domain": "googleapis.com", "metadata": { "method": "ccc.hosted.frontend.directory.v1.DirectoryGroups.List", "service": "admin.googleapis.com" } } ] } }
初始代码
UserCredential credential; using (var stream = new FileStream(jsonFile, FileMode.Open, FileAccess.Read)) { try { credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.FromStream(stream).Secrets, new[] { DirectoryService.Scope.AdminDirectoryCustomer, DirectoryService.Scope.AdminDirectoryGroupReadonly, DirectoryService.Scope.AdminDirectoryGroupMemberReadonly }, "user", CancellationToken.None); Debug.WriteLine("[1] credential=" + credential); var ser = new DirectoryService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "UpdateMailGroups" }); Debug.WriteLine("ser=" + ser); Debug.WriteLine("ser.Groups=" + ser.Groups); GroupsResource.ListRequest list = ser.Groups.List(); Debug.WriteLine("list=" + list); var e = list.Execute(); Debug.WriteLine("e=" + e); } catch (Exception ex) { Debug.WriteLine("exception: " + ex.Message); } }
排查与解决过程
尝试1:调整OAuth客户端与作用域
在APIs&Services/Credentials页面复制OAuth 2.0 Client ID,进入“Security/API Controls/Domain-wide Delegation”添加新API客户端,设置作用域为https://www.googleapis.com/auth/admin.directory.group.readonly,并修改代码仅请求AdminDirectoryGroupReadonly授权:credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.FromStream(stream).Secrets, new[] { DirectoryService.Scope.AdminDirectoryGroupReadonly }, "user", CancellationToken.None);仍出现相同的403权限不足错误。
尝试2:使用服务账号的Client ID配置域级授权
在“APIs&Services/Credentials”页面的“Service Accounts”区域,找到服务账号[company]-mail-updater@email-group-updater.iam.gserviceaccount.com,复制其Domain-wide Delegation对应的Client ID,回到“Security/API Controls/Domain-wide Delegation”页面添加该客户端并设置相同作用域,错误依旧。尝试3:修正授权的用户参数
将GoogleWebAuthorizationBroker.AuthorizeAsync()的"user"参数改为服务账号邮箱[company]-mail-updater@email-group-updater.iam.gserviceaccount.com,运行后浏览器弹出权限请求,授权后无身份验证错误,但调用list.Execute()时抛出400错误:GoogleApiException: The service admin has thrown an exception. HttpStatusCode is BadRequest. Bad Request Error=Google.Apis.Requests.RequestErrorBad Request [400] Errors [ Message[Bad Request] Location[ - ] Reason[badRequest] Domain[global] ] ErrorResponseContent={ "error": { "code": 400, "message": "Bad Request", "errors": [ { "message": "Bad Request", "domain": "global", "reason": "badRequest" } ] } }尝试4:指定请求的Domain参数
在调用list.Execute()前添加代码:list.Domain = <my website domain>问题得以解决!
内容的提问来源于stack exchange,提问作者Betty Crokker

