问题描述
我刚刚发现auth0存在问题,它与auth0配置受众有关.因此,当我明确地写给读者时,JWT验证失败,并显示错误The provided Algorithm doesn't match the one defined in the JWT's Header.
.当我不写给读者时,一切都会正常进行,除了现在每次令牌过期并且用户单击登录链接时,它都会跳过登录过程并立即使用先前的凭据登录.我不希望发生这种情况,我希望用户在令牌过期后仍然能够再次进行身份验证,就像我写给读者那样.
I just found out that I have a problem with auth0 and it relates to the auth0 configuration audience. So when I explicitly write the audience, the JWT verification failed with error The provided Algorithm doesn't match the one defined in the JWT's Header.
When I don't write the audience, everything will work fine, except now everytime the token expire and user click on login link it skip the login process and immediately logged in with the previous credential. I don't want this to happen, I want user to still authenticate themselves again after token expire, just like when I write the audience.
那么观众是什么,为什么它会影响这样的行为?
So what is audience and why does it affect the behaviour like this?
我该如何解决它以获得我想要的行为?
And How can I fix it to get the behaviour I wanted?
下面是Auth0的配置
Below is the configuration of the 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以及正确执行登录行为.
I need to know how I can make the JWT to be verified correctly as well as make the login behaviour correctly when the JWT expire.
推荐答案
Auth0可以发出两种类型的令牌:不透明令牌和JWT.
Auth0 can issue two types of tokens: opaque and JWT.
当您指定audience
参数时,您将收到一个JWT令牌. JWT与不透明令牌的不同之处在于它们是独立的,因此您可以直接在应用程序中对其进行验证.
When you specify the audience
parameter, you will receive a JWT token. JWTs differ from opaque tokens in that they are self-contained and therefore you verify them directly in your application.
在这种情况下,您收到的JWT的签名算法与验证逻辑中定义的算法不同.您可以使用 https://jwt.io 解码JWT,然后可以在alg
标头的属性.
In this case, the JWT you have received is signed with an algorithm different to that which you've defined in your verification logic. You can decode the JWT using https://jwt.io and you can see which algorithm it was signed with in the alg
attribute of the header.
您还可以在Auth0信息中心中找到您的API使用的签名算法.转到API,单击您的API,单击设置"选项卡,然后滚动到令牌设置".您将看到它列为签名算法".
You can also find out the signing algorithm your API uses in the Auth0 dashboard. Go APIs, click your API, click the Settings tab and then scroll to Token Setting. You will see it listed as the Signing Algorithm.
根据错误消息判断,您正在使用java-jwt
库,在这种情况下,您需要按照此处概述的步骤相应地更改签名算法: https://github.com/auth0/java-jwt#verify-a-token
Judging by the error message, you are using the java-jwt
library, in which case you will need change the signing algorithm accordingly per the steps outlined here: 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的签名秘诀.
Where secret
is your API's Signing Secret.
对于RS256,它涉及更多一点.首先,您需要解码令牌以从标头中检索kid
(密钥ID):
For RS256, it's a little more involved. You first need to decode the token to retrieve the kid
(key ID) from the header:
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
try {
DecodedJWT jwt = JWT.decode(token);
} catch (JWTDecodeException exception){
//Invalid token
}
然后,您需要使用 jwks-rsa-java 库来构造JwkProvider :
You then need to construct a JwkProvider using the jwks-rsa-java library:
JwkProvider provider = new UrlJwkProvider("https://your-domain.auth0.com/");
Jwk jwk = provider.get(jwt.getKeyId());
最后,您可以使用从JWKS检索到的公钥并将其用于验证令牌:
Finally, you can use the public key retrieved from the JWKS and use it to verify the token:
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
Keep in mind that it's preferred to use RS256 over HS256 for the reasons outlined here: https://auth0.com/docs/apis#signing-algorithms
您可能还会发现本文对于验证令牌的详细信息很有用: https://auth0.com/docs/api-auth/tutorials/verify-access-token
You may also find this article useful for detailed information on verifying tokens: https://auth0.com/docs/api-auth/tutorials/verify-access-token
这篇关于验证0配置受众的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!