Play Framework和JSON Web Token

j3d*_*j3d 19 authentication scala playframework jwt

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

Cos*_*lis 17

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

首先,创建一个私钥/公钥对(我使用了此代码的一部分).创建从文件系统初始化时加载密钥的身份验证对象.

使用这些键创建一个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()
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

鉴于上述情况,当您收到密钥时,您需要先验证签名,然后解密.为了验证,首先你尝试用它来解析它,com.nimbusds.jose.JWSObject.parse(my_token)只要它不会引发ParseExceptionverifyparse返回的JWSObject的调用,使用MACVerifier你之前创建的参数作为参数.如果verify返回true,则只需要调用getPayload.toString相同的JWSObject来获取经过验证的有效负载.

要解密您调用的已验证有效负载com.nimbusds.jwt.EncryptedJWT.parse,然后执行以下操作:

val decrypter = new RSADecrypter(privateKey.asInstanceOf[java.security.interfaces.RSAPrivateKey])
jwt.decrypt(decrypter)
Run Code Online (Sandbox Code Playgroud)

privateKey是从中返回的值KeyFactory.getInstance("RSA").generatePrivate.

然后,您可以获得声明集jwt.getJWTClaimsSet.

最后,关于设置授权头,我用了也提到原则我AngularJS客户端上这样做这篇文章.