我正在使用 jersey rest webservice 以及带有 RSA 签名令牌功能的 JWT 进行身份验证。我能够成功创建令牌并将其发送到前端。现在,在我做到这一点之后,我对验证令牌以及识别请求资源的用户感到困惑。
这里有几个问题:
- 我是否必须解码在前端收到的 jwt 令牌以检查声明?
- 如何识别请求后端资源的用户?
因为在 SO 上的少数帖子中,有些人说不需要在前端解码令牌(检查此链接),而其他站点上的其他示例显示了在前端解码令牌的示例,例如
现在我很困惑如何进一步了解我是否应该在前端实际解码令牌或保持原样?如果是这样,其他示例如何在前端显示解码,如下所示:
angular.module('app')
.factory('Auth', ['$http', '$localStorage', 'urls', function ($http, $localStorage, urls) {
function urlBase64Decode(str) {
var output = str.replace('-', '+').replace('_', '/');
switch (output.length % 4) {
case 0:
break;
case 2:
output += '==';
break;
case 3:
output += '=';
break;
default:
throw 'Illegal base64url string!';
}
return window.atob(output);
}
function getClaimsFromToken() {
var token = $localStorage.token;
var user = {};
if (typeof token !== 'undefined') {
var encoded = token.split('.')[1];
user = JSON.parse(urlBase64Decode(encoded));
}
return user;
}
我在这里使用的令牌示例:
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 auth0库中解码。是因为我使用的是公钥吗?