是否存在JWT的Scala实现或者至少有Play的示例?在发布this question之后,我在互联网上进一步搜索并找到了JWT的一些介绍。任何建议都会非常感激。
答案 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客户端上执行此操作。