环聊 OAuth - 范围无效:无法显示某些请求的范围

Hangout OAuth - Invalid Scope : Some requested scopes cannot be shown

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

向 url 发出 post 请求后,我收到 400 响应代码 -

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

参数是 内容类型:application/x-www-form-urlencoded httpMode:POST body:grant_type=jwt-bearer&assertion=assertion-token

注意:这完全可以正常工作。突然遇到这个问题。

交叉验证:jwt 生成,service_account_id 等...

错误响应: { “错误”:“invalid_scope”,“error_description”:“无法显示某些请求的范围”:[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: The email address of the user for which the application is requesting delegated access.

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

解决方案:

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

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

背景说明:

Chat API 可用于机器人管理自己的数据,而不是管理最终用户数据。因此,您只能使用服务帐户充当机器人,而不能冒充最终用户。

来自这个问题跟踪器 comment

At the present moment, Chat API can only be used to manage bot-related data (listing the spaces in which the bot is included, etc.). Using domain-wide delegation to manage regular users' data is not currently possible.

功能请求:

如果您希望能够通过聊天 API 使用您的服务帐户和域范围的授权访问普通用户的数据,您并不孤单。之前已在问题跟踪器中请求此功能:

我建议您 star the referenced issue 以便跟踪它并帮助确定它的优先级。

参考: