JWT签名与本地计算的签名不匹配

sta*_*ick 9 java token jwt

我在用

JwtBuilder builder = Jwts.builder()
                    .setId(user.getEmail())
                    .signWith(signatureAlgorithm, signingKey);
Run Code Online (Sandbox Code Playgroud)

然后创建一个令牌

Jwts.parser().setSigningKey(secret).parse(token);
Run Code Online (Sandbox Code Playgroud)

进行身份验证.当我在JUnit测试中运行它时,它工作正常.但是,当我通过REST调用验证作为标头传递的令牌时,身份验证因SignatureException而失败.我已经在HTTP调用的两端验证了令牌,并且令牌字符串是相同的.创建/认证的代码是静态的,因此,每一方的秘密都是相同的.任何线索

ped*_*ofb 9

static Key secret = MacProvider.generateKey(); 每次重新加载服务器时都会生成一个新的随机密钥,因为在加载类时会初始化静态变量

这意味着如果您发出JWT,它只有在服务器不重启时才有效.在SignatureException你得到的是因为签名密钥是不同的

您需要secret.getEncoded()在第一代之后存储签名密钥,并在模块启动时加载它


Dmy*_*hko 8

我遇到了同样的问题,我注意到在源代码中,每当他们转换签名密钥时,他们都会明确指定 UTF-8 编码。我尝试在解码令牌的同时更改编码:

 private Jws<Claims> decodeToken(String token) {
        return Jwts.parser()
                .setSigningKey(securityProperties.getTokenSecret().getBytes(Charset.forName("UTF-8")))
                .parseClaimsJws(token);
 }
Run Code Online (Sandbox Code Playgroud)

在签署令牌时:

private String getSignedToken(UserDetailsAdapter user, List<String> roles, byte[] signingKey) {
        return Jwts.builder()
                .signWith(Keys.hmacShaKeyFor(signingKey), SignatureAlgorithm.HS512)
                .setHeaderParam("typ", securityProperties.getTokenType())
                .setIssuer(guiServerSecurityProperties.getTokenIssuer())
                .setAudience(guiServerSecurityProperties.getTokenAudience())
                .setSubject(user.getUsername())
                .setExpiration(new Date(System.currentTimeMillis() + 864000000))
                .claim("rol", roles)
                .compact();
    }
Run Code Online (Sandbox Code Playgroud)

这是唯一为我解决这个问题的东西。


S.D*_*eko 7

我有一个类似的问题。就我而言,这是错误的令牌验证。我将符号设置为字节:

.signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret().getBytes())
Run Code Online (Sandbox Code Playgroud)

但是当我解析令牌并设置 signKey 时,我将其设置为字符串,而不是字节:

Jwts.parser().setSigningKey(signingKey).parseClaimsJws(this.token)
Run Code Online (Sandbox Code Playgroud)

在检查标记时也总是检查引号和空格,在标记的开始/结束处经常会有多余的空格/引号(使用 trim() 方法)


小智 5

我有一个类似的问题。在我的情况下,两个键是相同的,但由于某种原因,我收到了引号内的标记(例如,"Syasda.da3das.aDjty6"而不是仅Syasda.da3das.aDjty6)。

我花了很长时间才意识到这一点,因为大部分时间在 jwt.io 上进行测试时,我只会手动复制令牌而不用括号来验证它。

token = token.replace("\"",""); 
Run Code Online (Sandbox Code Playgroud)

删除这些引号为我解决了问题。希望这也能帮助其他人。