加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – EssentialAction:如何在不解析请求的情况下获取请求的

发布时间:2020-12-16 10:00:03 所属栏目:安全 来源:网络整理
导读:鉴于以下EssentialAction …… object MyController extends Controller { ... def HasToken(action: Token = EssentialAction) = EssentialAction { request = ... // this doesn't compile val body = request.body match { case json: JsValue = json.toS
鉴于以下EssentialAction ……

object MyController extends Controller {

  ...

  def HasToken(action: Token => EssentialAction) = EssentialAction { request =>

    ...

    // this doesn't compile
    val body = request.body match {
      case json: JsValue => json.toString
      case _ => ""
    }

    // calculate hash with body content here
    ...
  }

  // here is an authenticated action
  def getUser(userId: Strign) = HasToken { token =>
    Action(parse.json) { request =>
      request.body.validate[User] match {
        ...
      }
    }
  }
}

…如何在不解析请求的情况下获取请求的正文?

我不想要,而且我不需要在HasToken中解析请求体,因为将在操作getUser中解析正文.我只需要身体的原始内容来计算哈希值.

HasToken中的代码无法编译,因为请求的类型为RequestHeader,而我需要一个Request,它定义了body.

解决方法

这对你有用吗?

object MyController extends Controller {

  // Your HasToken Action
  def Authenticate(action: Token => EssentialAction) = EssentialAction { requestHeader =>
    // ... execute logic to verify authenticity using requestHeader
  }

  // Your action to validate tampering of request body and validity of JSON
  def Validate[A](action: Token => Request[A]) = Action(parse.json) { request =>
    val body = request.body
    body match {
      case json: JsValue => json.toString
      case _ => ""
    }
    // calculate hash with body content here

    body.validate[User] match {
      // ...
    }
  }

  def getUser(userId: Strign) = Authenticate { token =>
    Validate { user =>
      //.... Continue
    }
  }
}

>身份验证仅使用RequestHeader
>验证使用Request body. (奖励:身体只解析一次)

编辑:

问题1:我不想验证Validate中的正文…因为我需要一个可以在任何地方使用的通用验证机制,无论内容类型如何(例如用户,消息等).

如何添加另一个类型参数(以使其成为通用):

def Validate[A,B](action: Token => Request[A])(implicit reads: Reads[B]) = Action(parse.json) { request =>
   // ...
}

问题2:此外,如果令牌验证失败,则不必处理正文(这在文件上载的情况下很重要,当且仅当验证成功时才必须执行).在我看来,最好的选择是在Validate中读取正文的原始内容.

这很容易实现:

def Validate[A,B](action: Token => Request[A])(implicit reads: Reads[B]) = Action(parse.json) { request =>
   val body = request.body
    body match {
      case json: JsValue => json.toString
      case _ => ""
    }
    // calculate hash with body content here and figure out if the body is tampered
    if (bodyIsNotTampered) {
      body.validate[B] match {
        // ...
      }
    } else {
      // log and return Future.successful(BadRequest)
    }
  }

编辑3:完整解决方案:

import play.api.libs.json.{Json,JsValue,Format}

object CompilationUtils {
  class Token
  case class User(name: String)
  implicit val UserFormat = Json.format[User]

  def authenticate = new Token // authentication logic

  def isTampered(body: JsValue) = {
    val bodyAsStr: String = Json.stringify(body)
    // calculate hash with body content here
    false
  }

}

object MyController extends Controller {
  import CompilationUtils._

  // Your HasToken Action
  def Authenticate(action: Token => EssentialAction) = EssentialAction { requestHeader =>
    action(authenticate)(requestHeader) // your execute logic to verify authenticity using requestHeader
  }

  // Your action to validate tampering of request body and validity of JSON
  def Validate[A,B](request: Request[A])(implicit formatA: Format[A],formatB: Format[B]): Either[Result,B] = {
    val body = request.body
    val bodyAsJsValue = Json.toJson(body)
    if (!isTampered(bodyAsJsValue)) {
      bodyAsJsValue.validate[B].fold(
        valid   = res => Right(res),invalid = err => Left(BadRequest(err.toString))
      )
    } else {
      Left(BadRequest) // Request Tampered
    }
  }

  def getUser(userId: String) = Authenticate { token =>
    Action(parse.json) { request =>
      Validate(request).fold(
        badReq => badReq,user   =>
          // continue...
          Ok("")
      )
    }
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读