我正在使用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==另一方面,我认为在我的应用程序中有些东西丢失或配置错误,因为否则每个使用这个库的人都会遇到相同的问题。
因此,我的问题是:如何在这个场景中成功地验证访问令牌?
谢谢。
发布于 2019-04-05 16:08:04
我发现这个问题贯穿于两段代码的代码中,通过交互来执行验证。
原来,我使用的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);问题是,当应该根据base64将at_hash用base64url编码时,它将编码为这。
访问令牌哈希值。它的值是base64url值的ASCII表示的八进制哈希值的左半部分的哈希编码,其中使用的哈希算法是ID令牌的JOSE报头的alg参数头中使用的哈希算法。例如,如果alg是RS256,则使用SHA-256散列access_token值,然后取最左边的128位,base64url对它们进行编码。at_hash值是区分大小写的字符串。
这个问题在CAS的后续版本中得到了解决,至少我可以确认5.2.x通过将最后一行改为:
return EncodingUtils.encodeUrlSafeBase64(hashBytesLeftHalf);我希望这对任何面临同样问题的人都有帮助。
https://stackoverflow.com/questions/55498194
复制相似问题