Accessing request body in EssentialFilter before processing request

Since Play migrated to using Akka streams (version 2.5 +) I’ve been confused about how to access the request body via EssentialFilter before the request is processed.

Use case: validating that the request body matches hash in header.

With Play 2.4, this could be accomplished with Iteratees and Enumeratees:

override def apply(next: EssentialAction): EssentialAction = new EssentialAction {
  override def apply(request: RequestHeader) = {
    for {
      bufferedBody <- Iteratee.consume[Array[Byte]]()
      iteratee <- {
        val newRequest = Try { validateBody(bufferedBody) } match {
          case Success(_) => request.addHeader("Valid" -> "true")
          case _ => request.addHeader("Valid" -> "false")
    } yield iteratee

I’m finding that it’s not straightforward to do this in 2.5 and later.

I am not sure if a filter is the right place to access the request body.
Are you aware of action composition? It comes after filters are processed and you have the request body available via request.body.