Hangout OAuth-无效作用域:无法显示某些请求的作用域



我在为Hangout Scope的服务帐户生成令牌时遇到以下错误-https://www.googleapis.com/auth/chat.bot.

在哪里我收到400响应代码后,对这个网址的帖子请求-

https://www.googleapis.com/oauth2/v4/token

参数是内容类型:application/x-www-form-urlencodedhttpMode:POSTbody:grant_type=jwt承载&assertion=断言令牌

注意:这一切都很顺利。我突然面临这个问题

交叉验证:jwt生成、service_account_id等…

错误响应:{quot;Error":"invalid_scope","errordescription":"无法显示某些请求的作用域":[https://www.googleapis.com/auth/chat.bot]}

生成断言的代码:

//FORMING THE JWT HEADER
JSONObject header = new JSONObject();
header.put("alg", "RS256");
header.put("typ", "JWT");
//ENCODING THE HEADER
String encodedHeader = new String(encodeUrlSafe(header.toString().getBytes("UTF-8")));

//FORMING THE JWT CLAIM SET
JSONObject claimSet = new JSONObject();
claimSet.put("iss","123@hangout.iam.gserviceaccount.com");
claimSet.put("sub","one@domain.com");
claimSet.put("scope","https://www.googleapis.com/auth/chat.bot");
claimSet.put("aud","https://oauth2.googleapis.com/token");
long time = System.currentTimeMillis() / 1000;
claimSet.put("exp",time+3600);
claimSet.put("iat",time);
//ENCODING THE CLAIM SET
String encodedClaim = new String(encodeUrlSafe(claimSet.toString().getBytes("UTF-8")));
//GENERATING THE SIGNATURE
String password = "secretofkey", alias = "privatekey";
String signInput = encodedHeader + "." + encodedClaim;
Signature signature = Signature.getInstance("SHA256withRSA");

String filepath =   "/check/PrivateKeys/hangoutPKEY.p12";
KeyStore kstore = KeyStore.getInstance("PKCS12");
fis = new FileInputStream(filepath);
kstore.load(fis, password.toCharArray());
KeyStore.PrivateKeyEntry pke = (KeyStore.PrivateKeyEntry) kstore.getEntry(alias, new KeyStore.PasswordProtection(password.toCharArray()));
PrivateKey pKey = pke.getPrivateKey();
signature.initSign(pKey);
signature.update(signInput.getBytes("UTF-8"));
String encodedSign = new String(encodeUrlSafe(signature.sign()), "UTF-8");
//JWT GENERATION
String JWT = signInput + "." + encodedSign;
String grant_type = URLEncoder.encode("urn:ietf:params:oauth:grant-type:jwt-bearer");
reqBody = "grant_type=" + grant_type + "&assertion=" + JWT;  
public static byte[] encodeUrlSafe(byte[] data) {
Base64 encoder = new Base64();
byte[] encode = encoder.encodeBase64(data);
for (int i = 0; i < encode.length; i++) {
if (encode[i] == '+') {
encode[i] = '-';
} else if (encode[i] == '/') {
encode[i] = '_';
}
}
return encode;
}  

有人知道哪里出了问题吗?

简短回答:

您正试图使用域范围的权限来模拟常规帐户。这在聊天API中不受支持。

问题详细信息:

您在构建JWT索赔时使用了sub参数:

claimSet.put("sub","one@domain.com");

其中sub表示:

sub:应用程序请求委派访问的用户的电子邮件地址。

我注意到,如果我在测试代码中添加sub参数,我会得到与您相同的错误。

解决方案:

从代码中删除此行,以便使用服务帐户进行授权(无需模拟(并处理机器人程序数据:

claimSet.put("sub","one@domain.com");

背景说明:

聊天API可用于机器人管理自己的数据,而不是管理最终用户数据。因此,您只能使用服务帐户作为机器人,而不能模拟最终用户。

来自本问题跟踪评论:

目前,Chat API只能用于管理与僵尸程序相关的数据(列出包含僵尸程序的空间等(。使用域范围委派来管理常规用户的数据目前是不可能的。

功能请求:

如果您希望能够通过Chat API使用您的服务帐户和域委托访问常规用户的数据,您并不孤单。此功能以前曾在Issue Tracker:中请求过

  • 使用域范围的授权权限和服务帐户凭据访问普通用户的Google聊天

我建议你将引用的问题列为星号,以便跟踪它并帮助确定它的优先级。

参考:

  • 使用服务帐户
  • 将域范围的权限委派给服务帐户
  • 正在准备进行授权的API调用

最新更新