Java jjwt 为 JWT 创建无效 JSON
Java jjwt creating invalid JSON for JWT
我一定是漏了什么。我正在使用 JJWT 库来创建 JWT。根据声明中的数据集,从库中创建的 JWT 不一致。我的代码:
Date now = new Date();
Date expiration = new Date(now.getTime() + TimeUnit.MINUTES.toMillis(30));
Claims claims = Jwts.claims();
JSONObject jsonObject = new JSONObject();
jsonObject.put("serviceName1", "serviceStatus1");
jsonObject.put("serviceName2", "serviceStatus2");
claims.put("services",jsonObject);
claims.setSubject("225544");
claims.setExpiration(expiration);
claims.setId(UUID.randomUUID().toString());
claims.setIssuedAt(now);
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS256, Base64.encodeBase64(secret.getBytes()))
.compact();
此代码创建 JWT 并正确签名。然而,当有效载荷被解码时,有效载荷值并不总是有效的JSON。大多数情况下,它缺少结束 }
导致对其的任何解析失败。
如果 Subject
是 8 个字符,它工作正常。如果是7个或6个字符长,则无效JSON。或者,如果我在声明中添加其他标签,有时它会起作用,有时却不起作用。难道我做错了什么?
我也尝试过使用 Auth0 java-JWT 库并得到类似的结果,有效载荷并不总是有效 JSON。
请尝试 Map<String,String>
而不是 JSONObject
最终,我无法让 JJWT 库按我想要的方式工作。因此,我手动实现了一个简单的哈希算法和 jwt creator。这是它的样子:
Date now = new Date();
//Valid only for 30 minutes
Date expiration = new Date(now.getTime() + TimeUnit.MINUTES.toMillis(30));
JSONObject header = new JSONObject();
JSONObject payload = new JSONObject();
header.put("alg", "HS256");
payload.put("sub", "ourSubject");
payload.put("exp", expiration.getTime() / 1000);
payload.put("jti", UUID.randomUUID().toString());
payload.put("iat", now.getTime() / 1000);
payload.put("services", "JSON object of our custom data needed in authorization (not authentication");
String signature = "";
StringBuilder token = new StringBuilder();
token.append(new String(Base64.encodeBase64(header.toString().getBytes())));
token.append(".");
token.append(new String(Base64.encodeBase64(payload.toString().getBytes())));
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(Base64.encodeBase64((secret + otherPartOfSecret).getBytes()), "HmacSHA256");
sha256_HMAC.init(secret_key);
signature = new String(Base64.encodeBase64(sha256_HMAC.doFinal(token.toString().getBytes())));
} catch (Exception e) {
System.out.println("Error");
}
token.append(".");
token.append(signature);
return token.toString();
您可以使用toMap()
方法解决这个问题。
您的示例中的代码将如下所示:
JSONObject jsonObject = new JSONObject();
jsonObject.put("serviceName1", "serviceStatus1");
jsonObject.put("serviceName2", "serviceStatus2");
claims.put("services",jsonObject.toMap());
这将在 JWT 中产生以下声明。
"services": {
"serviceName1": "serviceStatus1",
"serviceName2": "serviceStatus2"
}
我一定是漏了什么。我正在使用 JJWT 库来创建 JWT。根据声明中的数据集,从库中创建的 JWT 不一致。我的代码:
Date now = new Date();
Date expiration = new Date(now.getTime() + TimeUnit.MINUTES.toMillis(30));
Claims claims = Jwts.claims();
JSONObject jsonObject = new JSONObject();
jsonObject.put("serviceName1", "serviceStatus1");
jsonObject.put("serviceName2", "serviceStatus2");
claims.put("services",jsonObject);
claims.setSubject("225544");
claims.setExpiration(expiration);
claims.setId(UUID.randomUUID().toString());
claims.setIssuedAt(now);
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS256, Base64.encodeBase64(secret.getBytes()))
.compact();
此代码创建 JWT 并正确签名。然而,当有效载荷被解码时,有效载荷值并不总是有效的JSON。大多数情况下,它缺少结束 }
导致对其的任何解析失败。
如果 Subject
是 8 个字符,它工作正常。如果是7个或6个字符长,则无效JSON。或者,如果我在声明中添加其他标签,有时它会起作用,有时却不起作用。难道我做错了什么?
我也尝试过使用 Auth0 java-JWT 库并得到类似的结果,有效载荷并不总是有效 JSON。
请尝试 Map<String,String>
JSONObject
最终,我无法让 JJWT 库按我想要的方式工作。因此,我手动实现了一个简单的哈希算法和 jwt creator。这是它的样子:
Date now = new Date();
//Valid only for 30 minutes
Date expiration = new Date(now.getTime() + TimeUnit.MINUTES.toMillis(30));
JSONObject header = new JSONObject();
JSONObject payload = new JSONObject();
header.put("alg", "HS256");
payload.put("sub", "ourSubject");
payload.put("exp", expiration.getTime() / 1000);
payload.put("jti", UUID.randomUUID().toString());
payload.put("iat", now.getTime() / 1000);
payload.put("services", "JSON object of our custom data needed in authorization (not authentication");
String signature = "";
StringBuilder token = new StringBuilder();
token.append(new String(Base64.encodeBase64(header.toString().getBytes())));
token.append(".");
token.append(new String(Base64.encodeBase64(payload.toString().getBytes())));
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(Base64.encodeBase64((secret + otherPartOfSecret).getBytes()), "HmacSHA256");
sha256_HMAC.init(secret_key);
signature = new String(Base64.encodeBase64(sha256_HMAC.doFinal(token.toString().getBytes())));
} catch (Exception e) {
System.out.println("Error");
}
token.append(".");
token.append(signature);
return token.toString();
您可以使用toMap()
方法解决这个问题。
您的示例中的代码将如下所示:
JSONObject jsonObject = new JSONObject();
jsonObject.put("serviceName1", "serviceStatus1");
jsonObject.put("serviceName2", "serviceStatus2");
claims.put("services",jsonObject.toMap());
这将在 JWT 中产生以下声明。
"services": {
"serviceName1": "serviceStatus1",
"serviceName2": "serviceStatus2"
}