Auth 0 configuration audience

2019-08-27 01:31发布

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?

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'
    });

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.

标签: jwt auth0
1条回答
看我几分像从前
2楼-- · 2019-08-27 01:40

Auth0 can issue two types of tokens: opaque and 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.

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.

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.

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

For 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
}

Where secret is your API's Signing Secret.

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
}

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(token.getKeyId());

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
}

Keep in mind that it's preferred to use RS256 over HS256 for the reasons outlined here: https://auth0.com/docs/apis#signing-algorithms

You may also find this article useful for detailed information on verifying tokens: https://auth0.com/docs/api-auth/tutorials/verify-access-token

查看更多
登录 后发表回答