Не удалось проверить токен доступа с помощью oidc-client-js и Apereo CAS - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь войти в систему с помощью Apereo CAS 5.1.1 в моем приложении реакции с использованием OIDC. В поисках библиотек для этого я приземлился на 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==

С другой стороны, я думаю, что в моем приложении что-то отсутствует или неправильно настроено, потому что в противном случае каждый, кто использует эту библиотеку, столкнется с той же проблемой.

Итак, мой вопрос: как я могу успешно проверить токен доступа в этом сценарии?

Спасибо.

1 Ответ

0 голосов
/ 05 апреля 2019

Я обнаружил проблему при прохождении кода обеих частей кода, взаимодействующих для выполнения проверки.

Оказалось, что в используемой мной версии 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 согласно this :

Значение хэша токена доступа.Его значение - это кодировка base64url самой левой половины хеша октетов представления ASCII значения access_token, где используемый алгоритм хеширования - это алгоритм хеширования, используемый в параметре заголовка alg заголовка JOSE идентификатора токена.Например, если alg - RS256, хэшируйте значение access_token с SHA-256, затем возьмите самые левые 128 битов и закодируйте их base64url.Значение at_hash является чувствительной к регистру строкой.

Эта проблема была решена в следующей версии CAS, по крайней мере, я могу подтвердить, что 5.2.x решил ее, изменив (среди прочего) последнюю строку на:

return EncodingUtils.encodeUrlSafeBase64(hashBytesLeftHalf);

Надеюсь, это может быть полезно любому, кто сталкивается с той же проблемой.

...