playframework / playframework/play-ws
[2.5.1] Request body not available in `WsSignatureCalculator`
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 224
- Forks
- 92
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 28
Description
Moved from https://github.com/playframework/playframework/issues/5996
Play Version (2.5.x / etc)
Play 2.5.1
API (Scala / Java / Neither / Both)
Scala
Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)
Ubuntu 14.04
Arch Linux Kernel 4.4.5-1
JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)
openjdk version "1.8.0_77"
OpenJDK Runtime Environment (build 1.8.0_77-b03)
OpenJDK 64-Bit Server VM (build 25.77-b03, mixed mode)
Expected Behavior
First let me give you some context: In order to secure our services we use HMAC signatures. So, when a client sends a request it calculates a signature based on some header fields and the body. It set the Authorization header to the signature and some meta data. On der server side, we implemented an Action which also calculates the signature and then verifies it is the same as the one in the request provided by the client.
On the server side everything works fine. For clients we implemented a WsSignatureCalculator which can be added to a WSRequest like this:
wsClient
.url("https:/localhost:9000/upload-some-file")
.sign(hmacSignatureCalculator)
.post(file)
And I also tried:
wsClient
.url("https:/localhost:9000/upload-some-file")
.withBody(FileBody(file))
.sign(hmacSignatureCalculator)
.execute("POST")
Please describe the expected behavior of the issue, starting from the first action.
- During
AhcWSRequest.buildRequestthehmacSignatureCalculatoris called with aRequestwhich provides the body of the actual request. - The SHA1 hash of the body is calculated and used to calculate the HMAC signature.
- The server accepts the request because the signature provided by the client is valid.
Actual Behavior
The body of the Request provided to hmacSignatureCalculator is alwaysnull. The same is true for Request.getFile and Request.getBodyGenerator.
- The body of the
Requestprovided tohmacSignatureCalculatoris not set. - The SHA1 hash cannot be calculated.
- The server calculates the SHA1 and thus a different HMAC signature and rejects the request.
With the underlying AsyncHttpClient the Request.getBody is not null.
val client: AsyncHttpClient = wsClient.underlying
val request = client
.preparePost(urls.uploadOrder(processId).toString)
.setSignatureCalculator(hmacSignatureCalculator)
.setBody(file)
.build()
val result = Promise[AhcWSResponse]()
client.executeRequest(request, new AsyncCompletionHandler[Response]() {
override def onCompleted(response: Response) = {
result.success(AhcWSResponse(response))
response
}
override def onThrowable(t: Throwable) = {
result.failure(t)
}
})
val responseFuture = result.future
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at AhcWSRequest.buildRequest and trace how the WSRequest body is passed to WsSignatureCalculator. Reproduce the reported post and withBody examples, comparing the Request passed to the calculator with the underlying AsyncHttpClient request. Done means the calculator can access the actual request body so the client and server compute the same HMAC signature.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, scala
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 43/100