Java 使用jwt令牌身份验证识别用户
我正在使用jersey rest webservice和JWT以及RSA签名令牌功能进行身份验证。我能够成功地创建令牌并将其发送到前端。现在,在我达到这一点之后,我对验证令牌和识别请求资源的用户感到困惑 这里有几个问题:Java 使用jwt令牌身份验证识别用户,java,angularjs,jersey,jwt,jose4j,Java,Angularjs,Jersey,Jwt,Jose4j,我正在使用jersey rest webservice和JWT以及RSA签名令牌功能进行身份验证。我能够成功地创建令牌并将其发送到前端。现在,在我达到这一点之后,我对验证令牌和识别请求资源的用户感到困惑 这里有几个问题: 我是否必须解码前端接收到的jwt令牌以检查 索赔 如何识别请求后端资源的用户 因为在上的一些帖子中,一些人说不需要解码前端的令牌(),而其他网站上的其他示例显示了解码前端令牌的示例,例如 现在,我很困惑如何进一步,究竟我应该在前端解码令牌,还是让它保持原样?如果是这样,为什么其
private void authenticate(String email, String password)
throws Exception {
try {
Connection con = DBConnection.getConnection();
PreparedStatement statement = con.prepareStatement("select USR_PRIMARY_EMAIL, USR_PASSWORD from TBL_USER where USR_PRIMARY_EMAIL=? and USR_PASSWORD=?");
statement.setString(1, email);
statement.setString(2, password);
ResultSet result = statement.executeQuery();
if (result.next()) {
System.out.println("User authenticated successfully");
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA");
keyGenerator.initialize(1024);
KeyPair kp = keyGenerator.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
JWSSigner signer = new RSASSASigner(privateKey);
JWTClaimsSet claimsSet = new JWTClaimsSet();
claimsSet.setSubject("alice");
claimsSet.setIssuer("https://c2id.com");
claimsSet.setExpirationTime(new Date(new Date().getTime() + 60 * 1000));
System.out.println("publicKey is: " + publicKey);
System.out.println("privateKey is: " + privateKey);
System.out.println("claimsSet is: " + claimsSet);
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256),claimsSet);
signedJWT.sign(signer);
token = signedJWT.serialize();
System.out.println("Token is: " + token);
signedJWT = SignedJWT.parse(token);
System.out.println("signedJWT is: " + signedJWT);
JWSVerifier verifier = new RSASSAVerifier(publicKey);
assertTrue(signedJWT.verify(verifier));
assertEquals("alice", signedJWT.getJWTClaimsSet().getSubject());
assertEquals("https://c2id.com", signedJWT.getJWTClaimsSet().getIssuer());
assertTrue(new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime()));
} else {
System.out.println("User doesn't exist");
}
} catch (Exception e) {
System.out.println("DB related Error");
e.printStackTrace();
}
}
还有一个问题是使用nimbus+jose_JWT(RSA签名)生成的令牌,我无法在angular库中解码。是因为我在使用公钥吗
我是否必须解码前端收到的jwt令牌以检查声明
对。JWT声明集是base64URL编码的JSON,因此需要解码才能读取它
如何识别请求后端资源的用户
sub
声明是可选的,但实际上每个JWT提供者都会发布所有令牌,其中包含标识请求者的主题ID。根据JWT规范:
“sub”(subject)索赔确定了作为
JWT的主题。JWT中的声明通常是声明
关于这个话题。subject值的作用域必须为
在发行人的上下文中是本地唯一的,或者是全球唯一的。
本索赔的处理通常是针对具体应用的。这个
“sub”值是包含StringOrURI的区分大小写的字符串
价值此声明的使用是可选的
还有一个问题是使用nimbus+jose_JWT(RSA签名)生成的令牌,我无法在angular auth0库中解码。是因为我在使用公钥吗
不需要。所有JWT声明集都是base64URL编码的JSON,独立于签名方法,因此您应该能够对其进行解码。HI Rodrigo。非常感谢你的回答。我现在能够正确解码令牌,但问题是它只返回有效负载信息,如
sub
、iss
和exp
,但没有标题和签名?我是否也需要这些值来标识用户?还要在标题中插入授权信息吗?或者仅仅有效负载信息就足够了?当调用接受JWT的API时,您只需在授权
头中传递整个JWT(例如授权:承载eyJ…
)。JWT库允许您在解码令牌时访问声明集。访问报头通常是不必要的,因为您应该事先知道所期望的签名算法(请参阅)。也没有必要手动访问签名,因为您应该直接使用库的验证方法。
private void authenticate(String email, String password)
throws Exception {
try {
Connection con = DBConnection.getConnection();
PreparedStatement statement = con.prepareStatement("select USR_PRIMARY_EMAIL, USR_PASSWORD from TBL_USER where USR_PRIMARY_EMAIL=? and USR_PASSWORD=?");
statement.setString(1, email);
statement.setString(2, password);
ResultSet result = statement.executeQuery();
if (result.next()) {
System.out.println("User authenticated successfully");
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA");
keyGenerator.initialize(1024);
KeyPair kp = keyGenerator.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
JWSSigner signer = new RSASSASigner(privateKey);
JWTClaimsSet claimsSet = new JWTClaimsSet();
claimsSet.setSubject("alice");
claimsSet.setIssuer("https://c2id.com");
claimsSet.setExpirationTime(new Date(new Date().getTime() + 60 * 1000));
System.out.println("publicKey is: " + publicKey);
System.out.println("privateKey is: " + privateKey);
System.out.println("claimsSet is: " + claimsSet);
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256),claimsSet);
signedJWT.sign(signer);
token = signedJWT.serialize();
System.out.println("Token is: " + token);
signedJWT = SignedJWT.parse(token);
System.out.println("signedJWT is: " + signedJWT);
JWSVerifier verifier = new RSASSAVerifier(publicKey);
assertTrue(signedJWT.verify(verifier));
assertEquals("alice", signedJWT.getJWTClaimsSet().getSubject());
assertEquals("https://c2id.com", signedJWT.getJWTClaimsSet().getIssuer());
assertTrue(new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime()));
} else {
System.out.println("User doesn't exist");
}
} catch (Exception e) {
System.out.println("DB related Error");
e.printStackTrace();
}
}