我正在尝试使用OIDC在我的React应用程序中以Apereo CAS 5.1.1登录。寻找图书馆来实现这一目标,我登陆了oidc-client-js 1.7.0,但是遇到了以下错误:
ResponseValidator._validateAccessToken:无法验证at_hash dWr5-bD5lv8C1x3VcfFn1Q dWr5 + bD5lv8C1x3VcfFn1Q ==
在跟踪之后,我发现了引发异常的地方
var a = s.substr(0, s.length / 2), u = this._joseUtil.hexToBase64Url(a);
return u !== e.profile.at_hash ?
(i.Log.error("ResponseValidator._validateAccessToken: Failed to validate at_hash", u, e.profile.at_hash), Promise.reject(new Error("Failed to validate at_hash"))) :
(i.Log.debug("ResponseValidator._validateAccessToken: success"), Promise.resolve(e));
问题在于this._joseUtil.hexToBase64Url(a)
不会添加填充(=
),在这种情况下,不会添加+
符号。这是因为URL中不接受这些字符。因此,总是(或几乎总是)比较是错误的。例如,在此执行中:
dWr5-bD5lv8C1x3VcfFn1Q != dWr5+bD5lv8C1x3VcfFn1Q==
另一方面,我认为我的应用程序中缺少某些东西或配置错误,因为否则使用此库的每个人都会遇到相同的问题。
因此,我的问题是:在这种情况下如何成功验证访问令牌?
谢谢。
答案 0 :(得分:0)
我发现遍历两个代码段的代码交互进行验证的问题。
事实证明,我正在使用的CAS版本(5.1.1)在创建访问令牌哈希at_hash
值时出错。
类org.apereo.cas.oidc.token.OidcIdTokenGeneratorService
具有以下方法:generateAccessTokenHash
。它实际生成哈希的最后几行代码是:
final byte[] digested = DigestUtils.rawDigest(hashAlg, tokenBytes);
final byte[] hashBytesLeftHalf = Arrays.copyOf(digested, digested.length / 2);
return EncodingUtils.encodeBase64(hashBytesLeftHalf);
问题在于,应根据this将at_hash
编码为base64url时,它将编码为base64:
访问令牌哈希值。它的值是 ASCII表示的八位字节的哈希值的最左半部分 的access_token值,其中使用的哈希算法是哈希 ID令牌的JOSE的alg标头参数中使用的算法 标头。例如,如果alg为RS256,则对access_token值进行哈希处理 使用SHA-256,然后采用最左边的128位和base64url编码 他们。 at_hash值是区分大小写的字符串。
此问题在以下版本的CAS中已解决,至少我可以通过将最后一行更改(除其他外)确认5.2.x已解决该问题:
return EncodingUtils.encodeUrlSafeBase64(hashBytesLeftHalf);
我希望这对面临相同问题的任何人都可以有所帮助。