Auth0 可以发布两种类型的令牌:不透明和 JWT。
当您指定 audience 参数时,您将收到一个 JWT 令牌。 JWT 与不透明令牌的不同之处在于它们是自包含的,因此您可以直接在应用程序中验证它们。
在这种情况下,您收到的 JWT 使用与您在验证逻辑中定义的算法不同的算法进行签名。您可以使用 https://jwt.io 对 JWT 进行解码,并且您可以在标头的 alg 属性中查看它是使用哪种算法签名的。
您还可以在 Auth0 仪表板中找到您的 API 使用的签名算法。转到 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(密钥 ID):
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
try {
DecodedJWT jwt = JWT.decode(token);
} catch (JWTDecodeException exception){
//Invalid token
}
然后您需要使用jwks-rsa-java 库构造一个 JwkProvider:
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