Play Framework& JSON Web令牌

时间:2014-03-18 13:02:52

标签: scala authentication playframework jwt

是否存在JWT的Scala实现或者至少有Play的示例?在发布this question之后,我在互联网上进一步搜索并找到了JWT的一些介绍。任何建议都会非常感激。

1 个答案:

答案 0 :(得分:17)

我在Nimbus-JOSE-JWT应用中使用spray.io,我很满意。执行身份验证的对象扩展了HttpAuthenticator,如果找到正确的JWT,则返回令牌主题和相关信息,否则为None(身份验证失败)。使用Play2,您可以使用like this实现HTTP Basic Auth。关于令我更感兴趣的令牌设置/获取:

首先,创建一个私钥/公钥对(我使用this code的部分)。创建在文件系统初始化时加载密钥的身份验证对象。

使用这些密钥创建一个com.nimbusds.jose.crypto.MACSigner和一个com.nimbusds.jose.crypto.MACVerifier。

每当你想设置一个密钥时,FIRST加密它,然后签名。加密:

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返回的JWSObject上抛出verify parse,使用as您之前创建的MACVerifier参数。如果verify返回true,则只需在同一个JWSObject上调用getPayload.toString即可获得经过验证的有效负载。

要解密已验证的有效负载,请在其上调用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客户端上执行此操作。