19

是否有 JWT 的 Scala 实现或至少有 Play 的示例?发布此问题后,我在 Internet 上进行了进一步搜索,并找到了 JWT 的一些介绍。任何建议将不胜感激。

4

1 回答 1

17

我在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)只要它不引发ParseExceptionverify对返回的 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 客户端上使用本文中提到的原则进行操作。

于 2014-04-21T07:52:21.933 回答