20

is it possible to pass some data in HTTP Header, while redirecting a request from one server to another.

Here is my scenario, I have one generic filter, via which every request is passing. Now, based on some condition, I'm redirecting the request to some different server using the API objHttpServletResponse.sendRedirect(strURL).

But, the issue is, when I'm setting some data in response header like objHttpServletResponse.setHeader("Key", "Value"); That's not available in the redirected server.

So, my questions are,

1. Is there any way to pass some data in header while redirecting a request?

2. If not, what are the other possible ways to send some data while redirecting a request?

Please Note: few other ways, like

using URL parameters: objHttpServletResponse.sendRedirect(strURL+"?param="+ strParamValue);

or

using session: HttpSession session = httpRequest.getSession(); session.setAttribute("Key", "Value");

is not what I'm expecting.

anij
  • 1,322
  • 5
  • 23
  • 39
  • Why do you need to store these values in the HTTP header? Why not somewhere else? – yannicuLar Jun 25 '14 at 07:21
  • >is it possible to pass some data in HTTP Header, while redirecting a request from one server to another. under the same domain? you can add the data in a cookie (there are some workarounds to use a cookie between different domains) – Emanuele Ivaldi Jun 25 '14 at 07:36
  • @yannicuLar I need pass a security token, because, else security filter from server 2 (where I'm redirecting) has one security filter, which will expect the token in header – anij Jun 25 '14 at 07:59
  • @EmanueleIvaldi see header is needed... else i can pass in any different formats. I'm send that also, but, I have to use one additional filter over the security filter which will fetch from the different location(cookies/url_param) and set it as header, before entering into the security filter – anij Jun 25 '14 at 08:00
  • 1
    @anij Yes I think that a pre security filter is the safest way to achieve what you want to do in this case, don't think that the browser can be instructed to change its own request headers (I am not a javascript magician so I may be wrong, and even so you would be bound to a javascript implementation, that's something I would not suggest). – Emanuele Ivaldi Jun 25 '14 at 08:28
  • @EmanueleIvaldi yeah.. I also don't want to do this with js – anij Jun 25 '14 at 09:14
  • Also see http://stackoverflow.com/q/12883385/632951 – Pacerier Feb 15 '17 at 05:58

5 Answers5

11

The headers you set are written to the response that gets sent to the client, along with a Location header and a status code. See Redirecting a request using servlets and the "setHeader" method not working

The client is then supposed to send an identical request to the URL you specified in the Location header. Identical to the request it sent to you.

You want the browser to send a header you specify along with the redirected request. Have you considered adding a (domain) Cookie header? Some googling leads me to believe that cookies set in a redirect response will get picked up by most browsers. See http://blog.dubbelboer.com/2012/11/25/302-cookie.html

Community
  • 1
  • 1
flup
  • 26,937
  • 7
  • 52
  • 74
  • Thanks for the reply, but in my scenario, I can't depend on browser session or cookies, because, request may come from some other clients also, like some http client is making request, then that time, these session and cookies, will not be available. – anij Jun 19 '14 at 13:12
  • JSESSIONID Cookies represent java sessions, but in general a HTTP Cookie header need not represent a server-side session. You'll only use this header to make sure the browser adds the header to the redirected request. – flup Jun 19 '14 at 13:31
  • Can you provide some examples or links .. about how to implement this, when the client is not browser, because I tried this [http://www.journaldev.com/1907/java-servlet-session-management-tutorial-with-examples-of-cookies-httpsession-and-url-rewriting] link... but doesn't work when calling from another app – anij Jun 20 '14 at 06:51
  • Using cookie header works only if the origin and the target server have the same domain (or have a domain-sub domain relationship). – fajarkoe Jun 20 '14 at 13:45
  • @fajarkoe true, I don't know of any way to add headers cross domains. – flup Jun 20 '14 at 14:03
  • I believe that it is not possible in general. Some servers use http header to prevent CSRF attacks (using referer header, or X-CSRF-Token header). – fajarkoe Jun 20 '14 at 14:05
  • Set variables in jsp and simply use them by request.getParameter. Is it not working?? – Tanu Garg Jun 23 '14 at 06:42
  • @TanuGarg The question is specifically about adding headers to an already submitted request. If your suggestion is to add the headers to the request before it gets submitted and redirected then yes, I think that can be a good idea. But it's not what is being asked here. – flup Jun 23 '14 at 10:38
  • @flup, Does this method require 2 redirects? In other words, the first `302` response you send has `Set-Cookie`, and redirect target set to your **own** domain, so that the browser would send a `Cookie` on the second request to your domain. And on the second response, you set a redirect to the target server so that the browser would send along the `Cookie` to that target server? – Pacerier Feb 15 '17 at 05:52
  • @Pacerier It's been a while but I think no, it's just a single redirect, with a Set-Cookie header. – flup Feb 19 '17 at 15:27
2

Please have a look at Apache HttpClient.

This example adds several parameters to the post request :

    String url = "https://selfsolve.apple.com/wcResults.do";

    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost(url);

    // add header
    post.setHeader("User-Agent", USER_AGENT);

    List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
    urlParameters.add(new BasicNameValuePair("sn", "C02G8416DRJM"));
    urlParameters.add(new BasicNameValuePair("cn", ""));
    urlParameters.add(new BasicNameValuePair("locale", ""));
    urlParameters.add(new BasicNameValuePair("caller", ""));
    urlParameters.add(new BasicNameValuePair("num", "12345"));

    post.setEntity(new UrlEncodedFormEntity(urlParameters));

    HttpResponse response = client.execute(post);
    System.out.println("Response Code : " 
                + response.getStatusLine().getStatusCode());
SparkOn
  • 8,806
  • 4
  • 29
  • 34
  • 1
    @M.Sharma but can we send header while redirecting a request using this Apache HttpClient – anij Jun 25 '14 at 07:16
  • Once we set the response using `HttpResponse response = client.execute(post); response.sendRedirect()` should do the trick – SparkOn Jun 25 '14 at 07:21
  • but i cant find any API named sendRedirect() under org.apache.http.HttpResponse. So, am I doing anything wrong? – anij Jun 25 '14 at 07:52
  • 1
    I mean Once we set the response using HttpResponse response = client.execute(post); it send the request to the specified url with the parameters attached – SparkOn Jun 25 '14 at 09:01
  • @M.Sharma Is it redirecting or simply calling from that point? – anij Jun 25 '14 at 09:58
  • I don't understand. HttpClient is a client, no? I thought the question is how to code the server's behavior. – flup Jun 25 '14 at 13:54
  • @M.Sharma but my friend.. It's making a fresh call from that point, that means, response will come back to the calling point. So, it is just a client. But, I just wants to redirect a call, that means, it will not come back, it will be a fresh call for that, new URL and response will goes back to the actual client, which is calling the 1st place. Now, the question, is, when I'm doing so, can I pass a header? ... – anij Jun 26 '14 at 07:20
  • ... example, suppose, Client 'A' is calling Server 'B', now 'B' is redirecting the call to Server 'C'. That means, 'C' will send the response back to 'A' not 'B'. Secondly, the criteria is, can I pass a Header from 'B' to 'C'. Usually, as far I know, it is not possible, because, while we redirect, it makes a fresh call from the client. So, any header data is usually discarded. But, Is there any way, to explicitly pass one header. Remember, client may be browser or some client app. – anij Jun 26 '14 at 07:20
  • I dint try that but i hope this link may help you. [refer](http://www.baeldung.com/httpclient-custom-http-header) – SparkOn Jun 26 '14 at 07:38
1

The problem is that the redirect() method of the response initiates a new request altogether, thereby loosing the attributes that were set before redirecting. Luckily there is a fluent way of solving the problem still.

response.setHeader("Key", "Value");
request.getRequestDispatcher("redirecturl").forward(request, response);

Then in your destination you can do

response.getHeaders("key")
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Adindu Stevens
  • 2,947
  • 3
  • 14
  • 20
0

You can use JS redirect, i.e. instead of calling sendRedirect return HTML page with embedded javascript that will do redirect setting headers you need.

However, using GET parameters is really the best solution. If you have concerns about users altering parameters manually - use MAC code to protect parameters.See Message authentication code

In simplest form, ?p1=1&p2=2&mac={mac value}, where {mac value} = md5('MY_SECRET_KEY' + 'p1=1&p2=2'). Receiving side can recalculate MAC and compare it with provided one. Since external users can not know 'MY_SECRET_KEY', they will not be able to make valid MAC.

Lakshmi
  • 2,204
  • 3
  • 29
  • 49
Sergey Alaev
  • 3,851
  • 2
  • 20
  • 35
  • No, actully, as per requirement spec, ?url_param or session or cookie is prohibited. – anij Jun 24 '14 at 11:49
0

Have you checked the HTTP request/response from/to server? You can use a number of plugins on chrome or firefox to check that. You would be able to see if value is being passed from your server to another server or not
Also retrieve the header using httpResponse.getHeader("Key"); not using request.getHeader("key"). One of my colleague was facing same issue some days back, he was using request to fetch header values

SVashisth
  • 131
  • 10
  • Yes I have tried to find in both request/response header, but, its not there. While, before redirection, I have checked the response header-list using this API: httpResponse.getHeaderNames() and it's there. Secondly, no, i never test with from/to server plugin. It will be if u can provide some plugin name. If you think, it's needed.\ – anij Jun 24 '14 at 11:41
  • You can check the raw request/response using 'Live HTTP Headers' or 'HTTP Spy' in chrome. 'Live HTTP Headers' is available for firefox as well or you can use HttpFox – SVashisth Jun 25 '14 at 13:39