我正在使用
JwtBuilder builder = Jwts.builder()
.setId(user.getEmail())
.signWith(signatureAlgorithm, signingKey);
然后创建一个令牌
Jwts.parser().setSigningKey(secret).parse(token);
进行身份验证。当我在JUnit测试中运行它时,它工作正常。但是,当我通过REST调用验证作为标头传递的令牌时,身份验证会因SignatureException而失败。我已经在HTTP调用的两端验证了令牌,并且令牌字符串是相同的。创建/认证的代码是静态的,因此,每一方的秘密都是相同的。任何线索
答案 0 :(得分:8)
static Key secret = MacProvider.generateKey();
都会生成一个新的随机密钥,因为在加载类时会初始化静态变量
这意味着如果您发出JWT,只有在服务器不重启时它才有效。您获得的SignatureException
是因为签名密钥不同
您需要在第一代后存储签名密钥secret.getEncoded()
,并在模块启动时加载
答案 1 :(得分:2)
我遇到了同样的问题,我注意到在源代码中,只要他们转换签名密钥,它们就会明确指定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();
}
这是唯一为我解决此问题的方法。
答案 2 :(得分:1)
我有类似的问题。在我的情况下,两个键都相同,但是由于某种原因,我在引号内收到了令牌(例如"Syasda.da3das.aDjty6"
而不是Syasda.da3das.aDjty6
)。
我花了很多时间来实现这一点,因为在大多数时候,在jwt.io上进行测试时,我只是手动复制令牌而没有括号来进行验证。
token = token.replace("\"","");
删除这些引号为我解决了这个问题。希望这也会对其他人有所帮助。
答案 3 :(得分:1)
可能存在两种类型的问题:
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
时,secretKeyFor
都会生成一个不同的随机密钥。因此,如果您想生成一个常量密钥,请尝试使用此密钥 public SecretKey generalKey(){
String stringKey = Global.JWT_SECRET;
byte[] encodedKey =Base64.decodeBase64(stringKey);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length,
"HmacSHA512");
return key;
}
答案 4 :(得分:0)
我有类似的问题。就我而言,这是错误的令牌验证。我将符号设置为字节:
.signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret().getBytes())
但是当我解析令牌并设置signKey时,我将其设置为字符串,而不是字节:
Jwts.parser().setSigningKey(signingKey).parseClaimsJws(this.token)
在检查令牌时也要经常检查引号和空格,令牌的开头/结尾经常会出现多余的空格/引号(使用trim()方法)
答案 5 :(得分:0)
我解决了在URL REST端点中修改HOST的问题。它有一个错误的主机,该主机返回了未经授权的HTTP 401错误。