In our web application, for security reason, the query string (for GET request) and request body (for POST) were encrypted by client and should be decrypted before the playframework routes the request to an action, and after that the response needs to be encrypted before it being sent to client. the encrypt/decrypt key can be got from a request header.

Action composition and filters do not work for this scenario, since the action handler defined in the controller will check the parameter type.

I can decrypt the query string in the Global's onRouteRequest method, and create a wrapped request with decrypted query parameters. but I don't know how to get the body since there is only one paramter "RequestHeader" in the onRouteRequest method.

1

There are 1 best solutions below

2
On

You can write your own action handler to preprocess your body.

You basically wrap another Action-handler around your Actions:

def index = Decrypt {
  Action { request =>
    Ok("Hello " + user.name)      
  }
}

The Decrypt-function could look something like this:

def Decrypt[A](action: User => Action[A]): Action[A] = {
  // Wrap the original BodyParser with authentication
  val decryptBodyParser = parse.using { request =>
    //decrypt stuff goes here...
  }
  // Now let's define the new Action
  Action(decryptBodyParser) { request =>
    action(request))
  }
}

Note: This is pseudo code inspired by the documentation (link is below). It should get you an idea though on how to handle stuff.

Check out the documentation about "ActionsComposition" and have a look at their "Authenticated"-Examples: https://www.playframework.com/documentation/2.0/ScalaActionsComposition