scala - Scalatra response HMAC calulation -
I am developing a web service using Skallet and I want to use HMAC for bidirectional authentication.
So far, I have implemented client authentication to the customer: Customer (an Android app) uses these criteria to calculate one HMAC / SHA 512 for each request: a shared secret, HTTP The method, URL, some headers (timestamp, client id etc) and request body (if it is a post or a string), this HMAC is then added to a specific title and the request is sent to the server (which is sent to HMAC Confirms with Acmsi in Nurod header that performs the same calculation to the client).
Now, I want to do the opposite thing: The server is certified to the client using shared secret, request HTTP method, URL and response body .
By now, I found that I can override renderResponse (ActionResult: any) that
, renderResponseBody (ActionResult: any)
or even That seems to be the easiest to handle as renderPipeline
and override renderpipline
as I decided to go along with.
Renderpipline
in my interchangeable I change the reaction body to a byte array file
if the file
is saved in the memory ), Calculate HMAC and add it to the feedback
header.
What do I want to know: In such cases when the renderpipline is overridden
this method will either break the authentication functionality presented above (such as Renderpipline
Which is not being called multiple times or is referred to the header which is sent to renderPipeline
) body or some other functionality in Scalatra?
As a note I do not calculate HMAC when the action unit
returns and the reaction output is being written directly by the action.
The problem was the only problem for me. I used a special feature to extend the handler
, as if it has been done and it is used as a reference implementation.
I created a ServletOutputStreamCopier
for the original OutputStream
and each byte for both streams:
class ServletOutputStreamCopier ( Original: ServletOutputStream: ServletOutputStream extends {Val copy: ByteArrayOutputStream = new ByteArrayOutputStream (1024) Def override write (b: int): unit = {orig.write (b) copy.write (b) Override def setWriteListener (writeListener: writeListener) : Unit = orig.setWriteListener def isReady override: boolean = orig.isReady def getCopy: array [byte] = copy.toByteArray}
Then a ResponseCopier
Which is a HttpServletResponse Wrapper is pre-defined with
service outoutstream copier
and copy
to the outside:
class ResponseCo Pier (res: HttpServletResponse, sos: ServletOutputStreamCopier, w: PrintWriter) HttpServletResponseWrapper (res) {extride def getOutputStream: ServletOutputStream = New servletOptputCopier (SOS) Override Def GetWriter: PrintWriter = w Override DRF SetSentant Lang (I: Int) = {} def GetCopy: Array [byte] = sos.getCopy}
Finally handle
method by using callback sclelet Class action takes care of adding the header after the completion of ScalatraBase.onRenderedComplete
.
Attribute SignedResponseSupport extends handler {self: ScalatraBase = & gt; , = New ResponseCopier (Response Unit = {withRequestResponse (Request, Race) {Val sosc = New ServletOutputStreamCopier (res.getOutputStream) Val = New PrintWriter (sosc) Wrapped: Summary Override Def Handle (Request: HttpServletRequest, Race: HttpServletResponse) Sosc, w) ScalatraBase.onRenderedCompleted {_ = & gt; W.flush () w.close () Val password = "secret-password" val sign = signResponseBody (wrapped.getCopy, password) wrapped.addHeader ("X-post-sign", sign)}} super.handle (request , Wrapped)} def signResponseBody (body: array [byte], password: string): string = {/ * signaling goes here} /
Comments
Post a Comment