#jwt #auth0
#jwt #auth0
Вопрос:
Я только что узнал, что у меня проблема с auth0, и это связано с аудиторией конфигурации auth0. Итак, когда я явно пишу аудиторию, проверка JWT завершилась с ошибкой The provided Algorithm doesn't match the one defined in the JWT's Header.
Когда я не пишу аудиторию, все будет работать нормально, за исключением того, что теперь каждый раз, когда срок действия токена истекает и пользователь нажимает на ссылку для входа, он пропускает процесс входа и немедленно входит в систему с предыдущими учетными данными. Я не хочу, чтобы это происходило, я хочу, чтобы пользователь по-прежнему аутентифицировался снова после истечения срока действия токена, точно так же, как когда я пишу аудиторию.
Итак, что такое audience и почему это влияет на подобное поведение?
И как я могу это исправить, чтобы получить желаемое поведение?
Ниже приведена конфигурация Auth0
auth0 = new auth0.WebAuth({
clientID: environment.auth0ClientId,
domain: environment.auth0Domain,
responseType: 'token id_token',
//Below is the audience I'm talking about
audience: '${constants.MY_APP}/userinfo',
redirectUri: `${constants.ORIGIN_URL}/auth`,
scope: 'openid email'
});
Мне нужно знать, как я могу обеспечить правильную проверку JWT, а также корректное поведение при входе в систему по истечении срока действия JWT.
Ответ №1:
Auth0 может выдавать два типа токенов: opaque и JWT.
Когда вы укажете audience
параметр, вы получите токен JWT. JWT отличаются от непрозрачных токенов тем, что они автономны, и поэтому вы проверяете их непосредственно в своем приложении.
В этом случае полученный вами JWT подписан алгоритмом, отличным от того, который вы определили в своей логике проверки. Вы можете декодировать JWT с помощью https://jwt.io и вы можете увидеть, с помощью какого алгоритма она была подписана, в alg
атрибуте заголовка.
Вы также можете узнать алгоритм подписи, используемый вашим API, на панели мониторинга Auth0. Перейдите в API, выберите свой API, перейдите на вкладку Настройки, а затем перейдите к настройке токена. Вы увидите это в списке как алгоритм подписи.
Судя по сообщению об ошибке, вы используете java-jwt
библиотеку, и в этом случае вам нужно будет соответствующим образом изменить алгоритм подписи в соответствии с описанными здесь шагами: https://github.com/auth0/java-jwt#verify-a-token
Для HS256:
try {
Algorithm algorithm = Algorithm.HMAC256("secret");
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build(); //Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
} catch (JWTVerificationException exception){
//Invalid signature/claims
}
Где secret
находится секрет подписи вашего API.
Для RS256 это немного сложнее. Сначала вам нужно декодировать токен, чтобы получить kid
(идентификатор ключа) из заголовка:
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
try {
DecodedJWT jwt = JWT.decode(token);
} catch (JWTDecodeException exception){
//Invalid token
}
Затем вам нужно создать JwkProvider, используя библиотеку jwks-rsa-java:
JwkProvider provider = new UrlJwkProvider("https://your-domain.auth0.com/");
Jwk jwk = provider.get(jwt.getKeyId());
Наконец, вы можете использовать открытый ключ, полученный из JWKS, и использовать его для проверки токена:
RSAPublicKey publicKey = (RSAPublicKey) jwk.getPublicKey();
try {
Algorithm algorithm = Algorithm.RSA256(publicKey, null);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build(); //Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
} catch (JWTVerificationException exception) {
//Invalid signature/claims
}
Имейте в виду, что предпочтительнее использовать RS256 вместо HS256 по причинам, изложенным здесь: https://auth0.com/docs/apis#signing-algorithms
Вы также можете счесть эту статью полезной для получения подробной информации о проверке токенов: https://auth0.com/docs/api-auth/tutorials/verify-access-token
Комментарии:
1. Отличная проработка, действительно помогла мне!