Play 框架和 JSON Web 令牌
Posted
技术标签:
【中文标题】Play 框架和 JSON Web 令牌【英文标题】:Play Framework & JSON Web Token 【发布时间】:2014-04-24 04:26:51 【问题描述】:是否有 JWT 的 Scala 实现或至少有 Play 的示例?在发布了this question 之后,我在 Internet 上进行了进一步搜索,发现了一些 JWT 的介绍。任何建议将不胜感激。
【问题讨论】:
【参考方案1】:我在spray.io 应用程序中使用Nimbus-JOSE-JWT,对此我非常满意。执行身份验证的对象扩展了 HttpAuthenticator,如果找到正确的 JWT,则返回令牌主题和相关信息,否则返回 None(身份验证失败)。使用 Play2,您可以使用 like this 实现 HTTP 基本身份验证。关于我认为您更感兴趣的令牌设置/获取:
首先,创建一个私钥/公钥对(我使用了this code 的一部分)。创建从文件系统初始化时加载密钥的身份验证对象。
使用这些密钥创建一个 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
,您就可以在parse
返回的JWSObject 上调用verify
,使用您所返回的MACVerifier
作为参数较早创建。如果verify
返回true
,你只需要在同一个JWSObject上调用getPayload.toString
就可以得到验证的payload。
要解密经过验证的有效载荷,您可以在其上调用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 标头,我正在使用this post 中提到的原则在我的 AngularJS 客户端上执行此操作。
【讨论】:
是的,您所描述的或多或少是我所做的。我也使用 nimbusds……但我不加密 JWT……我只是用应用程序的秘密对其进行签名,以确保它没有被篡改。由于我使用 HTTPS,令牌加密只是无用的开销。无论如何,非常感谢您的出色解释:-)以上是关于Play 框架和 JSON Web 令牌的主要内容,如果未能解决你的问题,请参考以下文章