鉴于
trait CipherService {
def decryptData(data: Array[Byte])(implicit ec: ExecutionContext): Future[DecryptionError \/ Array[Byte]
def encryptEncrypt(data: Array[Byte)(implicit ec: ExecutionContext): Future[EncryptionError \/ Array[Byte]]
}
如何使用EssentialFilter
实现请求解密和响应加密?感觉我被Enumeratee
和Iteratee
API困住了。
答案 0 :(得分:0)
当你达到字节块的极限时,Iteratees和Enumeratees几乎就要走了。加密是一种非常低级别的操作,并且很难做到正确,因此这些工具同样是低级别,小型和精确的。
由于加密和解密数据很难做到,因此大多数Web框架都依赖于HTTPS而不是在应用程序层中实现它。
如果你正在使用HTTP,那么根据bettercrypto.org使用配置了OpenSSL的nginx:https://www.playframework.com/documentation/2.3.x/ConfiguringHttps
如果您在内部使用安全性并且想要通过网络加密数据,则应在传输模式下使用ipsec。
答案 1 :(得分:0)
trait CipherService {
def decryptData(data: Array[Byte])(implicit ec: ExecutionContext): Future[DecryptionError \/ Array[Byte]]
def encryptData(data: Array[Byte])(implicit ec: ExecutionContext): Future[EncryptionError \/ Array[Byte]]
}
trait BodyEncryptionFilter extends EssentialFilter with Results {
import play.api.libs.concurrent.Execution.Implicits._
val cipher: CipherService
def apply(next: EssentialAction): EssentialAction = new EssentialAction {
override def apply(requestHeader: RequestHeader): Iteratee[Array[Byte], Result] =
Iteratee.consume[Array[Byte]]().mapM { encryptedBody => // Collect body bytes
cipher.decryptData(encryptedBody) // Decrypt data
.toEitherT // Monad transformer
.flatMapF { decryptedBody =>
Enumerator(decryptedBody).run(next(requestHeader)) // Feed decrypted data to filter/action chain
.flatMap { result => // Here is the action result
result.body.run(Iteratee.consume[Array[Byte]]()) //Collect result body data
.flatMap { body =>
cipher.encryptData(body) // Ecnrypt body data
.toEitherT
.map { encryptedBody =>
result.copy(body = Enumerator(encryptedBody)) // Wrap it with Enumerator and copy result
}
.leftMap(_ => BadRequest("Encryption error")) // You will probably want proper error handling
.merge
}
}
.map(_.right)
}
.leftMap(_ => BadRequest("Encryption error"))
.merge
}
}
}