跨Google Workspace使用service account创建Google Calendar事件报403如何解决
错误原因
- 核心问题是JWT认证的
subject参数配置错误:你当前把subject设为了服务账号本身的ID,但跨域全域权限委托的场景下,服务账号本身不属于账号B的Google Workspace域,也没有被单独授予账号B资源日历的写入权限,你需要让服务账号模拟账号B域内、拥有该资源日历写入权限的真实用户身份,才能执行写入操作。 - 读取操作能正常执行是因为账号B的资源日历默认开启了全域内用户可读权限,所以哪怕身份识别异常也能读取,但写入操作需要明确的身份授权,所以触发403报错。
- 单账号场景下能正常运行,是因为你在账号A内大概率给服务账号单独添加了对应日历的写入权限,不需要模拟域内用户也能操作。
- 你当前在账号B域内给服务账号配置的全域委托权限本身是正确的,不需要调整。
解决方法
有两种可选方案:
方案1:使用全域委托模拟域内用户(推荐)
- 先确认账号B域内有一个拥有目标资源日历写入权限的用户(可以是普通工作区用户,也可以是管理员),记录该用户的邮箱地址。
- 修改JWT初始化代码,把
subject参数的值从服务账号ID替换为上述的模拟用户邮箱即可:
// clientMail is the service account id // privateKey is the service account key // subject 替换为账号B域内有日历写入权限的用户邮箱 const impersonateUser = 'xxx@你的账号B域名.com'; const jwtClient = new google.auth.JWT( clientMail, undefined, privateKey, [ 'https://www.googleapis.com/auth/calendar', ], impersonateUser, ); let calendar = google.calendar({ version: 'v3', auth: jwtClient, }); ... savedEvent = (await calendar.events.insert({ calendarId, requestBody: event })).data; ...
方案2:直接给服务账号授予日历权限
如果你不想模拟真实用户,也可以直接操作账号B的目标资源日历的共享设置,添加服务账号的邮箱作为共享用户,授予编辑日历权限,这种场景下不需要修改现有代码的subject参数,直接用服务账号本身的身份就能完成写入操作。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

