【问题标题】:Token signature invalid error令牌签名无效错误
【发布时间】:2018-07-22 20:32:15
【问题描述】:

我抛出了这个错误

com.auth0.jwt.exceptions.SignatureVerificationException:使用算法验证时,令牌的签名无效:HmacSHA256

private static String SECRET = "some secret...";

public static DecodedJWT verify(String token) throws JWTVerificationException, UnsupportedEncodingException {
    JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET))
            .withIssuer("auth0")
            .acceptLeeway(1)
            .acceptExpiresAt(5 * 60)
            .build();

    return verifier.verify(token);
}

秘密有问题吗,在网站 jwt.io 我点击秘密 base 64 编码然后它变成蓝色。

我尝试使用https://www.base64encode.net 以base 64 编码我的秘密,但同样的问题。请指教。

【问题讨论】:

  • 你能分享一下这个秘密吗?
  • 是的zZrq0sZK1yt9RJk51RTJ/jeU6WERbvr8nqKMWQJRX1E=
  • 我在 jwt.io 上得到无效签名
  • 按下右下角的base 64编码复选框
  • 知道了,能分享一下token的例子吗?

标签: java jwt


【解决方案1】:

javadoc 表示您需要提供原始秘密值。 这意味着您需要base64-decode 您当前拥有的值:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class JwtVerification {

    private static final String SECRET = "zZrq0sZK1yt9RJk51RTJ/jeU6WERbvr8nqKMWQJRX1E=";

    public static DecodedJWT verify(String token) throws JWTVerificationException, UnsupportedEncodingException {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(Base64.getDecoder().decode(SECRET)))
                .withIssuer("auth0")
                .acceptLeeway(1)
                .acceptExpiresAt(5 * 60)
                .build();

        return verifier.verify(token);
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        final String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0aWQiOiJiZWJlMjM4Zi1iMGM4LTQwYzMtOTYyMC1jZDRlOGUyMzIwZGMiLCJvaWQiOiI5MjJjMmZiNC0zNWI1LTExZDctOWE2NC0wMGIwZDBmY2I5ZTMiLCJzdWIiOiI5MjJjMmZiNC0zNWI1LTExZDctOWE2NC0wMGIwZDBmY2I5ZTMiLCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJpYXQiOjE1MTg0NDk5NzYsImV4cCI6MTUxODQ1MzU3NiwibmJmIjoxNTE4NDQ5OTc2fQ.6InknrU67g_HEkaLxD9Ul5vOzbYGf54mJNcSyPr-xek";
        System.out.println(verify(token));
    }
}

我目前收到此异常,但它看起来像是令牌本身的问题:

Exception in thread "main" com.auth0.jwt.exceptions.InvalidClaimException: The Claim 'iss' value doesn't match the required one.
    at com.auth0.jwt.JWTVerifier.assertValidStringClaim(JWTVerifier.java:424)
    at com.auth0.jwt.JWTVerifier.verifyClaims(JWTVerifier.java:382)
    at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:355)
    at com.swiftkey.parametron.data.JWT2.verify(JWT2.java:23)
    at com.swiftkey.parametron.data.JWT2.main(JWT2.java:28)

确实,令牌没有指定iss 字段,但验证者认为它是“auth0”,因为.withIssuer("auth0")

如果您查看令牌内部:

        final String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0aWQiOiJiZWJlMjM4Zi1iMGM4LTQwYzMtOTYyMC1jZDRlOGUyMzIwZGMiLCJvaWQiOiI5MjJjMmZiNC0zNWI1LTExZDctOWE2NC0wMGIwZDBmY2I5ZTMiLCJzdWIiOiI5MjJjMmZiNC0zNWI1LTExZDctOWE2NC0wMGIwZDBmY2I5ZTMiLCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJpYXQiOjE1MTg0NDk5NzYsImV4cCI6MTUxODQ1MzU3NiwibmJmIjoxNTE4NDQ5OTc2fQ.6InknrU67g_HEkaLxD9Ul5vOzbYGf54mJNcSyPr-xek";
        final DecodedJWT decodedJwt = JWT.decode(token);
        System.out.println("Header =  " + decodedJwt.getHeader());
        System.out.println("Algorithm =  " + decodedJwt.getAlgorithm());
        System.out.println("Audience =  " + decodedJwt.getAudience());
        decodedJwt.getClaims().forEach((k, v) -> {
            System.out.println("Claim " + k + " = " + v.asString());
        });
        System.out.println("ContentType =  " + decodedJwt.getContentType());
        System.out.println("ExpiresAt =  " + decodedJwt.getExpiresAt());
        System.out.println("Id =  " + decodedJwt.getId());
        System.out.println("Issuer =  " + decodedJwt.getIssuer());
        System.out.println("Subject =  " + decodedJwt.getSubject());

你会看到Issuer字段是null

Header =  eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
Algorithm =  HS256
Audience =  null
Claim sub = 922c2fb4-35b5-11d7-9a64-00b0d0fcb9e3
Claim nbf = null
Claim oid = 922c2fb4-35b5-11d7-9a64-00b0d0fcb9e3
Claim exp = null
Claim iat = null
Claim tid = bebe238f-b0c8-40c3-9620-cd4e8e2320dc
Claim email = test@test.com
ContentType =  null
ExpiresAt =  Mon Feb 12 16:39:36 GMT 2018
Id =  null
Issuer =  null
Subject =  922c2fb4-35b5-11d7-9a64-00b0d0fcb9e3

生成该令牌的人没有指定Issuer(又名iss)字段。 因此验证失败,因为我们将验证者设置为期望 iss 等于 auth0

【讨论】:

  • 有一个 iss 字段但我删除了它,请让我尝试使用 Base64 代码
  • 好的,更进一步,下一个错误,The Claim 'iss' value doesn't match the required one. iss 令牌中的值有些专有,并且具有如下所示的值,https://subdomain.example.com/bebe238f-b0c8-40c3-9620-cd4e8e2320dc
  • 当我评论 .withIssuer("auth0") 时,它起作用了,你能帮我了解更多关于 iss.withIssuer 的信息
  • 更新了答案。如果它回答了您的问题,请点赞并接受它
  • 谢谢,issuer这个字段有什么用,是否有助于发行方之间的识别,是不是可以有任何自定义值的字段?试图了解发行人实际上是什么?
【解决方案2】:

issuer-field 通常是一个类似 url 的值。如果您的应用程序的 auth0 域是 yourcompany.eu.auth0.com,则颁发者很可能是 https://yourcompany.eu.auth0.com/

尝试改变

    .withIssuer("auth0")

    .withIssuer("https://yourcompany.eu.auth0.com/")

在创建验证器时。

【讨论】:

    猜你喜欢
    • 2020-10-24
    • 2020-06-21
    • 2017-03-28
    • 1970-01-01
    • 2021-06-21
    • 2017-05-30
    • 2017-10-15
    • 2011-10-25
    • 2017-10-16
    相关资源
    最近更新 更多