【问题标题】:JWT "invalid_grant" in Signature in Google OAuth2Google OAuth2 中签名中的 JWT“invalid_grant”
【发布时间】:2016-09-23 15:24:51
【问题描述】:

我正在编写一些代码来尝试从 Google 获取用于 OAuth2 的令牌。这是一个服务帐户,所以这里是说明:

https://developers.google.com/identity/protocols/OAuth2ServiceAccount

当我将 JWT 发布到 Google 时,我不断收到此错误:

{ "error": "invalid_grant", "error_description": "无效的 JWT 签名。" }

代码如下:

try{        
    var nowInSeconds : Number = (Date.now() / 1000);
    nowInSeconds = Math.round(nowInSeconds);
    var fiftyNineMinutesFromNowInSeconds : Number = nowInSeconds + (59 * 60);


    var claimSet : Object = {};
    claimSet.iss   = "{{RemovedForPrivacy}}";        
    claimSet.scope = "https://www.googleapis.com/auth/plus.business.manage";
    claimSet.aud   = "https://www.googleapis.com/oauth2/v4/token";
    claimSet.iat   = nowInSeconds; 
    claimSet.exp   = fiftyNineMinutesFromNowInSeconds;

    var header : Object = {};
    header.alg = "RS256";
    header.typ = "JWT";

    /* Stringify These */
    var claimSetString = JSON.stringify(claimSet);
    var headerString = JSON.stringify(header);

    /* Base64 Encode These */
    var claimSetBaseSixtyFour = StringUtils.encodeBase64(claimSetString);
    var headerBaseSixtyFour = StringUtils.encodeBase64(headerString);

    var privateKey = "{{RemovedForPrivacy}}";

    /* Create the signature */
    var signature : Signature = Signature();
    signature =  signature.sign(headerBaseSixtyFour + "." + claimSetBaseSixtyFour, privateKey , "SHA256withRSA");

    /* Concatenate the whole JWT */
    var JWT = headerBaseSixtyFour + "." + claimSetBaseSixtyFour + "." + signature;

    /* Set Grant Type */
    var grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"

    /* Create and encode the body of the token post request */
    var assertions : String = "grant_type=" + dw.crypto.Encoding.toURI(grantType) + "&assertion=" + dw.crypto.Encoding.toURI(JWT);

    /* Connect to Google And Ask for Token */
    /* TODO Upload Certs? */
    var httpClient : HTTPClient = new HTTPClient();
    httpClient.setRequestHeader("content-type", "application/x-www-form-urlencoded; charset=utf-8");
    httpClient.timeout = 30000;
    httpClient.open('POST', "https://www.googleapis.com/oauth2/v4/token");
    httpClient.send(assertions);

    if (httpClient.statusCode == 200) {
       //nothing
    } else {
       pdict.errorMessage = httpClient.errorText;
    }  

}
catch(e){
    Logger.error("The error with the OAuth Token Generator is --> " + e);
}

有人知道 JWT 失败的原因吗?

非常感谢! 布拉德

【问题讨论】:

  • 从云控制台检查您的服务帐户私钥是否仍然有效
  • 那是打字稿吗?你能用使用的语言标记问题吗?
  • @Brad 你找到解决方案了吗?

标签: oauth-2.0 jwt


【解决方案1】:

我在使用服务帐户时也出现了同样的错误。我不知道出了什么问题,所以第二天我又回来了,它奏效了。因此,Google Cloud 每隔一段时间可能需要一些时间来传播。

【讨论】:

    【解决方案2】:

    此错误的另一个原因可能是“您的服务帐户未激活”,从 Cloud SDK 安装 gsutil 后,您应该使用服务帐户凭据进行身份验证。

    1- 使用现有服务帐户或创建一个新帐户,然后下载相关的私钥。

    2- 使用 gcloud auth activate-service-account 与服务帐户进行身份验证:

    gcloud auth activate-service-account --key-file [KEY_FILE]
    

    其中 [KEY_FILE] 是包含您的服务帐户凭据的文件的名称。

    更多详情链接:Activate service account

    【讨论】:

      【解决方案3】:

      我之前也遇到过同样的问题,这就是问题所在:

      • 错误的应用程序名称(项目 ID)
      • 错误的服务帐户 ID(电子邮件)

      【讨论】:

        【解决方案4】:

        问题可能与您的 StringUtils.encodeBase64() 方法可能执行标准 base64 编码有关。

        然而,根据JWT spec,需要使用的不是标准的base64编码,而是the URL- and filename-safe Base64 encoding,省略了=填充字符。

        如果你没有方便的 base64URL 编码实用方法,你可以通过

        • 将所有+ 替换为-
        • 将所有/ 替换为_
        • 删除所有=

        在您的 base64 编码字符串中。

        另外,您的签名也是 base64 编码的吗?必须遵循上述相同的规则。

        【讨论】:

        • 罗比,这非常有帮助。快速提问...我从 Google 下载的密钥看起来像这样... -----BEGIN PRIVATE KEY-----\n{Bunch of stuff removed}=\n-----END PRIVATE KEY-----\n 在使用密钥签名之前,我是否删除了以下任何内容? “\n”或“-----BEGIN PRIVATE KEY-----”或“-----END PRIVATE KEY-----\n”之前的“=”
        • 不应该。
        • 谢谢先生。那正是我的问题。我能够使用来自 commons-codec 的Base64.encodeBase64URLSafeString
        猜你喜欢
        • 2018-10-04
        • 2020-09-01
        • 2014-03-24
        • 2023-03-03
        • 2014-09-22
        • 2016-03-05
        • 2021-06-15
        • 2016-10-30
        • 2017-07-27
        相关资源
        最近更新 更多