JWT" invalid_grant"在Google OAuth2中的签名中

时间:2016-05-25 20:29:02

标签: oauth-2.0 jwt

我正在编写一些代码,试图在OAuth2中获取Google使用的令牌。这是针对服务帐户的,因此说明如下:

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

当我将JWT发布到Google时,我一直收到此错误:

{"错误":" 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失败的原因?

非常感谢! 布拉德

4 个答案:

答案 0 :(得分:4)

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

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

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

进行验证
  • 将所有+替换为-;
  • 将所有/替换为_;
  • 删除所有=
在你的base64编码的字符串中

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

答案 1 :(得分:3)

之前我遇到过同样的问题,这是错误的:

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

答案 2 :(得分:0)

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

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

2-使用gcloud auth激活服务帐户对服务帐户进行身份验证:

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

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

链接以获取更多详细信息:Activate service account

答案 3 :(得分:0)

使用服务帐户时,我也发生了同样的错误。我不知道出了什么问题,所以第二天我又回来了,它奏效了。因此,也许Google Cloud有时需要花费一些时间进行传播。