I need to send multipart/form-data content to a web server and receive and parse multipart/form-data in the response. I have read multiple posts about how multipart content can be sent to server and parsed on the server. For ex: see here. But I found no post online that talks about sending a binary file and some other key-value pairs from server to client (a pojo or android activity in my case). Any help will be much appreciated.
I waited for a while and found no answers to my question. I have found a solution myself. Although I dont think its the most efficient, it removes the hurdle and lets me proceed. Here is the solution:
On the sender's side (server or client): Use org.apache.commons.codec.binary.Base64 to encodeToString(byte[] fileRepresentedAsBytes) and send HTTP Content-Type=text/plain.
On the receiver side (server or client): Use org.apache.commons.codec.binary.Base64.decode method to get the bytes[] back and create your file from it.
Here is the code for the http servlet:
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
File file = new File(<your-file-here>);
Base64 b = new Base64();
String fileStr = b.encodeToString(IOUtils.toByteArray(new FileInputStream(file)));
String queryString = "file=" + fileStr + "&foo=bar";
resp.setHeader("Content-Type", "text/plain");
resp.getWriter().print(queryString);
resp.getWriter().flush();
resp.getWriter().close();
}
On the client side, just use a query string parser from apache http utils and use Base64.decode. This will enable you to pass file and other plain text params between client and server. Remember that the client in my case is a POJO object and not a browser. Thats why I say it doesn't matter if you want to send a file from client to server or from server to client.
Ill be happy to learn alternate, more efficient methods if someone can post them here.
Related
I read a lot about Spring Securitys CSRF protection, but i still struggle a little bit. Now the documentation is great as usual, but it's completely based on the idea that you render html code on the server and are able to add a hidden field to every form. Now since i use AngularJS and JavaScript to call the backend this is not really an option.
So what is the best way to actually get the Token to the client in this case (Rest Backend / AngularJS frontend)? AngularJS seems to have built in support for CSRF in $resource and expects a Cookie called "XSRF-TOKEN" to retrieve the Token and send it as http header "X-XSRF-TOKEN" in further requests. So every request will contain the http header, as well as the cookie. Now on server side i could read the header and compare it to the Token i stored in the session.
The problem i have with this, it that it seems a bit complicated. Since the login itself has to be protected it would require creating a temporary session, just for the CSRF token. Is this really necessary?
Maybe this is just a stupid question, but why can't i just create a random-token on client side and set it as HTTP header and cookie on client side. This would be similar to "OWASP double submit cookie", but generate the Token on client-side. That way the server would not require to have a session before login, since he could just compare the 2 submitted tokens. Now while the attacker could send the HTTP header, he would per same-origin-policy have no way of reading or setting the cookie and could not get a match as long as the number is practically unguessable.
Now instinctly generating a secure token on client side seems dangerous to me and i guess i coul avoid it.. but WHY? I feel like i am missed something, surely there is a good reason why SpringSecurity stores the token in the session, right?
Please enlighten me :)
I ended up using spring-security-csrf-token-interceptor-extended, which reads the CSRF-Token from the http-header "X-CSRF-TOKEN" (name is configurable) and sends it as http-header on further requests.
Now the only thing i had to to was getting Spring-Security to send the Token as HTTP Header (since i don't render html code on serverside and therefor can't add it as a hidden field).
<security:http ....
<security:custom-filter ref="csrfTokenResponseHeaderBindingFilter" after="CSRF_FILTER"/>
....
</security:http>
The filter basically runs after the normal CSRF_FILTER and reads the "_csrf" request-attribute (which is put there by CSRF_FILTER) and sets it as header "X-CSRF-TOKEN"
public class CsrfTokenResponseHeaderBindingFilter extends OncePerRequestFilter {
protected static final String REQUEST_ATTRIBUTE_NAME = "_csrf";
protected static final String RESPONSE_TOKEN_NAME = "X-CSRF-TOKEN";
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException {
CsrfToken token = (CsrfToken) request.getAttribute(REQUEST_ATTRIBUTE_NAME);
if (token != null) {
response.setHeader(RESPONSE_TOKEN_NAME, token.getToken());
}
filterChain.doFilter(request, response);
}
}
We're invoking a secured SOAP WebService using Camel CXF deployed in Fuse. In the client, we have configured TrustStore and Keystore as per the standard config. We're able to hit the server via Netscaler. The server is generating the response and sending it back to Netscaler.
When the response is received from Netscaler, it is encrypted and should be decrypted by Camel CXF. The decryption is not happening and on the client we get a parsing error since the response is all encrypted.
Any clues of what could be the problem ?
The only stackTrace that I see is that the message failed to parse because of the presence of Ctrl characters since the message is encrypted.
<http:conduit name="https.*">
<http:tlsClientParameters secureSocketProtocol="TLS">
<sec:keyManagers ref="keyManagersBean"/>
<sec:trustManagers ref="trustManagersBean"/>
</http:tlsClientParameters>
</http:conduit>
The keyManager and trustManager beans are created using a custom factory.
Also, could this issue be because apart from transport level encryption, we also need message level encryption ?
This problem was resolved. The issue was the the content was gzipped before being sent from NetScaler. Hence, after transport level decryption we could still see the headers but not the content. Adding a GZip in & fault interceptor on the CXF endpoint fixed the issue.
I was trying to send a file using mail but I wanted to first it open in a draft mail like mailto in jsp. I had implemented mail to functionality in Java but I am not able to attach file to opened mail.
other are working file except the attachment.
here is my code:
public static void mailto(List<String> recipients, String subject,
String body) throws IOException, URISyntaxException {
String uriStr = String.format("mailto:%s?subject=%s&body=%s",
recipients,subject,body);
Desktop.getDesktop().browse(new URI(uriStr));
}
can any one suggest me how to attach file using mailto or any other api that can useful for me.enter code here
thanks in advance.
Create Multipart MimeMessage using JavaMail but instead sending it
call MimeMessage.saveChanges then use MimeMessage.writeTo to save it to the filesystem as '.eml'. Then open that file with java.awt.Desktop.open to launch the email client. You'll have to handle clean up after the email client is closed.
You also have to think about the security implications of email messages being left on the file system.
I have an Apache camel application which talks with a web service. This is purely a integration(mediation) application. We take REST request and transform it to a SOAP message (using VM templates) and call the web service. Receive response from web service, transform it to JSON and send back to our client.
REST ---->transform to SOAP req (Velocity template) ---->call WS ---->receive response---->transform into JSON---->return response to caller.
We are using servlet endpoint to receive request from our client. We can obtain HttpSession object from exchange before calling web service as follows :
HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class);
HttpSession session = req.getSession();
However, the problem is that I cannot obtain HTTPSession from exchange after receiving response from web service. If I check the Exchange object in debug mode, the Exchange.getIn() is of type DefaultMessage rather than HttpMessage. That is the reason I think I loose Request and response objects.
I tried setting the exchange pattern to InOut but that doesn’t help.
The only solution I could find is to store the original body of the in message in a header or a property and retrieve it at the end. But I think there must be a better solution that this.
Could anybody help please?
Note: We need HttpSession so that we can store corresponding session information like session id created on WS for the session created by our request. We cannot pass session information created on WS to our callers, and need a place on our application to hold this mapping info. HttpSession serves this requirement. Is there any better way?
You can store the http session as an exchange property, camel copy these properties across the exchanges, so you can access it in the route when you need.
I'm working on a C coded server that have to reply to browsers' requests. It have to give authentication when using url like this:
http://user:pass#website/
but I really don't know how or where get this information on my server, because what I got when I read the request is the same that I can read when I interact with the server simply using
http://website/
Second question is that sometime I have this favicon.ico request from browsers.. what can I reply to the browser to say "I have not this fu*** stupid icon"? :D
I'm of course using socket for this
Look for a request header named Authorization: containing the string Basic followed by the BASE64 encoded username and password. This method of authenticating is called HTTP Basic Authentication.
For the favicon, simply respond with a HTTP 404 response if you don't have one.