是否有 JWT 的 Scala 实现或至少有 Play 的示例?发布此问题后,我在 Internet 上进行了进一步搜索,并找到了 JWT 的一些介绍。任何建议将不胜感激。
1 回答
我在spray.io应用程序中使用Nimbus-JOSE-JWT ,对此我非常满意。执行身份验证的对象扩展了 HttpAuthenticator,如果找到正确的 JWT,则返回令牌主题和相关信息,否则返回 None(身份验证失败)。使用 Play2,您可以使用类似这样的方式实现 HTTP 基本身份验证。关于我认为您更感兴趣的令牌设置/获取:
首先,创建一个私钥/公钥对(我使用了这段代码的一部分)。创建从文件系统初始化时加载密钥的身份验证对象。
使用这些密钥创建一个 com.nimbusds.jose.crypto.MACSigner 和一个 com.nimbusds.jose.crypto.MACVerifier。
每当您想设置密钥时,首先对其进行加密,然后对其进行签名。加密:
private def encrypt(subject: String) = {
val header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A128GCM)
val jwt = new EncryptedJWT(header, claimSet(subject))
val encrypter = new RSAEncrypter(publicKey.asInstanceOf[java.security.interfaces.RSAPublicKey])
jwt.encrypt(encrypter)
jwt.serialize()
}
claimSet 方法可预测地返回一组声明:
def claimSet(subject: String) = {
val jwtClaims = new JWTClaimsSet()
jwtClaims.setIssuer(Config.JWT.issuer)
jwtClaims.setSubject(subject)
jwtClaims.setJWTID(java.util.UUID.randomUUID().toString())
jwtClaims
}
该publicKey
属性是从 返回的值KeyFactory.getInstance("RSA").generatePublic
。
签署:
private def sign(jwt: String) = {
val jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), new Payload(jwt))
jwsObject.sign(Tokens.signer)
jwsObject.serialize
}
鉴于上述情况,当您收到密钥时,您需要先验证签名,然后再解密。为了验证,首先您尝试解析它,com.nimbusds.jose.JWSObject.parse(my_token)
只要它不引发ParseException
您verify
对返回的 JWSObject的调用parse
,使用您之前创建的作为参数MACVerifier
。如果verify
返回true
,您只需要调用getPayload.toString
同一个 JWSObject 即可获取已验证的有效负载。
要解密您调用的经过验证的有效负载,请com.nimbusds.jwt.EncryptedJWT.parse
执行以下操作:
val decrypter = new RSADecrypter(privateKey.asInstanceOf[java.security.interfaces.RSAPrivateKey])
jwt.decrypt(decrypter)
privateKey
是从返回的值KeyFactory.getInstance("RSA").generatePrivate
。
然后,您可以使用 获取声明集jwt.getJWTClaimsSet
。
最后,关于设置 Authorization 标头,我在我的 AngularJS 客户端上使用本文中提到的原则进行此操作。