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

新手上路,请多包涵

我在用

JwtBuilder builder = Jwts.builder()
                    .setId(user.getEmail())
                    .signWith(signatureAlgorithm, signingKey);

然后创建一个令牌

Jwts.parser().setSigningKey(secret).parse(token);

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

原文由 stanlick 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 809
2 个回答

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

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

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

原文由 pedrofb 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

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

在签署令牌时:

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

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

原文由 Dmytro Kostyushko 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题