【发布时间】:2021-10-27 05:46:15
【问题描述】:
编辑:
URL 必须是https://admin.googleapis.com/admin/directory/v1/groups/{groupKey}/members 而不是https://admin.googleapis.com/admin/directory/v1/groups/{groupKey}/members/insert(没有insert,即使它是insert 方法)
我正在尝试使用 Google Apps 脚本构建一个脚本,该脚本能够将用户添加到具有服务帐户的 Google 群组。现在,使用AdminDirectory 服务很简单,所以这段代码可以工作:
const addUser = email => {
const member = AdminDirectory.Members.insert(
{ email, role: 'MEMBER' },
'test-group@domain.com'
);
};
但是,此服务需要超级用户权限。因此我决定使用服务帐号。
我创建了服务帐号并通过the whole checklist:
- 我生成了 JSON 密钥
- 启用域范围的委派
- 在管理控制台 > 安全 > API 控制 > 域范围委派中,我添加了以下范围:
- 然后我构建了这个使用OAuth2 library的解决方案:
const addUserWithServiceAccount = email => {
const serviceAccount = {
type: 'service_account',
project_id: 'my-tools-324016',
private_key_id: '021623b...',
private_key: '-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----\n',
client_email: 'SERVICE-ACCOUNT-EMAIL',
client_id: '1059879019...',
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
token_uri: 'https://oauth2.googleapis.com/token',
auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
client_x509_cert_url:
'https://www.googleapis.com/robot/v1/metadata/x509/...',
};
const _getAdminService = serviceAccount => {
return OAuth2.createService('admin-sdk-test')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(serviceAccount.private_key)
.setIssuer(serviceAccount.client_email)
.setPropertyStore(PropertiesService.getScriptProperties())
.setCache(CacheService.getUserCache())
.setLock(LockService.getUserLock())
.setScope([
'https://www.googleapis.com/auth/admin.directory.group',
'https://www.googleapis.com/auth/admin.directory.group.member',
'https://www.googleapis.com/auth/admin.directory.user',
]);
};
const _executeWithAuth2 = (groupKey, email) => {
console.log('_executeWithAuth2()');
const adminService = _getAdminService(serviceAccount);
if (!adminService.hasAccess()) {
Logger.log('ERROR n' + adminService.getLastError());
return;
}
const url = `https://admin.googleapis.com/admin/directory/v1/groups/${groupKey}/members/insert?memberKey=${email}`;
const headers = {
Authorization: `Bearer ${adminService.getAccessToken()}`,
// 'Content-Type': 'application/json',
};
const options = {
method: 'put',
headers,
contentType: 'application/json',
payload: JSON.stringify({
email,
role: 'MEMBER',
kind: 'admin#directory#member',
type: 'USER',
}),
muteHttpExceptions: true,
};
console.log(`fetch(${url}, ${JSON.stringify(options, null, 2)})`);
const result = UrlFetchApp.fetch(url, options).getContentText();
console.log(result);
return result;
};
return _executeWithAuth2('test-group@domain', email);
};
现在当我运行它时,我得到以下错误响应:
{
"error": {
"code": 403,
"message": "Not Authorized to access this resource/api",
"errors": [
{
"message": "Not Authorized to access this resource/api",
"domain": "global",
"reason": "forbidden"
}
]
}
}
当我将 PUT 切换到 POST 时,我得到:
在此服务器上找不到请求的 URL
/admin/directory/v1/groups/test-group@domain.com/members/insert?memberKey=user@domain.com。
但是,此方法使用服务帐户 works very well with BigQuery。尽管我无法找到特定于管理目录的解决方案,但我希望它能够以相同的方式工作。
我在这里错过了什么?
【问题讨论】:
标签: google-apps-script google-cloud-platform oauth-2.0 service-accounts