Hi,
On 05/01/12 01:44, VirtuallyReal wrote:
I am working on a system which will repond to client queries in clear-text,
to allow caching by proxies, CDNs, ISP and anyone who wishes to do so.
However, it is important for me to provide a way for end users to be able to
validate that the message content was not modified. So, I would like to sign
every response coming from the server.
The system is RESTful, so I am trying to use HTTP headers to communicate the
signature back. I am using tomcat 7.0.21 with CXF 2.4.1.
A response may have a erstream (file download), or a POJO (a serialized
object) as an entity, or may have no entity at all (redirection, or HEAD, or
...). In all these cases, I want to sign the headers in a certain order and
insert one header, and sign the entity (if there is one) and insert another
entity.
Can you explain please a bit how do you attach an entity signature in
case of files and POJOs; I'm presuming that in the former case it is
another (multi)part but what about the latter ?
The reason I ask is that in CXF 2.5.0 we offer some initial support for
signing XML payloads, see:
http://cxf.apache.org/docs/jax-rs-xml-security.html#JAX-RSXMLSecurity-XMLSignature
This works one way at the moment (from the client to the server), as
opposed to the encryption support. So I'd like to see what can we offer
at the CXF level to make the outbound signatures work too, for XML but
also for other payloads.
Actually, reading further, did you mean to say 'insert another header'
above ? Probably yes, still would be interested in your opinion as to
what can be generalized at the CXF level
In terms of implementation, I got it partially working. The implementation
injects a POST_MARSHAL out-interceptor generates the signatures and inserts
the headers of interest.
When the response does not include an entity, it works great. When there is
any body it does not work. Even though I add the signature, it is never sent
out.
After spending sometime debugging, I found the cause to be in the
org.apache.cxf.transport.http.AbstractHTTPDestination class. Even a POJO is
serialized into a stream, and when the first write happens the
onFirstWrite() method calls flushHeaders() which copies the headers as they
are prior to the marshalling. Since the signature is added in post_marshal,
it is never picked up.
For the case where there is no entity, since there is no first-write, the
headers are copied much later, and hence they make it out.
So, essentially the problem is boiled down to having the ability to re-flush
the headers, in the post_marshal phase, or at least to update the flushed
headers.
Couple questions:
- Is what I am doing reasonable? I would think this is a faced and solved
problem, but could not find any documentation to help me.
- Is there a (clean) way of extracting the coyoteResponse from a given
message and add headers to it.
This is how I handle this case in JAXRSOutInterceptor:
private boolean isResponseHeadersCopied(Message message) {
return
MessageUtils.isTrue(message.get(AbstractHTTPDestination.RESPONSE_HEADERS_COPIED));
}
and then
if (isResponseHeadersCopied) {
HttpServletResponse response =
(HttpServletResponse)message.get(AbstractHTTPDestination.HTTP_RESPONSE);
response.setStatus(status);
// or in your case, add some header
}
HTH, Sergey
Any help will be greatly appreciated.
--
View this message in context:
http://cxf.547215.n5.nabble.com/Attaching-digital-signature-to-a-server-response-tp5121287p5121287.html
Sent from the cxf-user mailing list archive at Nabble.com.
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com