2

From what I have read, it is impossible to send a cookie across domains, (as I understand the browser blocks them for privacy reasons). However I hope someone can tell me about a work around.

I've achieved this in our .Net winForms client, however I can't get it to work on our web software.

Scenario: I have my web site, this needs to call a 3rd party system that uses a rest implementation with XML that exists inside the customers firewall and can not be accessed from outside of their offices (VPN is not an option either).

I set my cookie:

$.cookie('name', 'value', {path : '/', domain : '192.168.254.164'});

and make post request

$.post(call, function(d) {}, 'text')
.success(function(d) {... /*do something*/

However, the cookie is not sent (see my request and response headers below)

Request Headers
Accept    text/plain, */*; q=0.01
Accept-Encoding   gzip, deflate
Accept-Language   en-gb,en;q=0.5
Connection    keep-alive
Host  192.168.254.164:8080
Origin    http://localhost:27249
Referer   http://localhost:27249/index.html
User-Agent    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0


Response Headers
Access-Control-Allow-Orig...  http://localhost:27249
Cache-Control no-cache
Content-Type  application/xml;charset=UTF-8
Date  Tue, 01 May 2012 15:14:58 GMT
Server    Sun Java System Application Server 9.1_01
Set-Cookie    JSESSIONID=8f7fbcd40348c0b5d912830bca8a; Path=/App
Transfer-Encoding chunked
X-Powered-By  Servlet/2.5

The response I receive tells me that I am unauthorised (this is because the cookie is not set).

I can not modify anything on the 3rd party's server, so on proxy's and I can't use JSONP as everything is in XML.

For debugging I tried to read the cookie before I send, but it results in 'null':

alert($.cookie(_svcMnuCookieSessionIdKey));

I'm new to web dev, so this may be a strange question - but as you can see from the response header I believe I am receiving a cookie (I receive the same cookie when I log in) - as the browser deals with cookies, shouldn't it save it and apply it to my requests automatically? rather than me having to manually add it as above? though saying that, the JSESSIONID looks to have different values in both requests and the spec says I must use the original JSESSIONID I get when I've logged in as the value of my cookie.

In my .Net app I do it similar to this:

 Dim httpWebRequest As Net.HttpWebRequest = CType(Net.WebRequest.Create("http://192.168.254.164:8080/App/RestfulService"), Net.HttpWebRequest)

 httpWebRequest.UserAgent = My.Application.Info.AssemblyName
 httpWebRequest.KeepAlive = True 'set the connection keep-alive (this is the default)
 httpWebRequest.Headers.Set(Net.HttpRequestHeader.Pragma, "no-cache") 'we don't want caching to take place so we need to set the pragma header to say we don't want caching
 httpWebRequest.Method = "POST"

 If Not String.IsNullOrEmpty(_sessionId) Then 'it isn't used on some request, so don't add it if it is nothing
     Dim cookie As New System.Net.Cookie("JSESSIONID", _sessionId)
     cookie.Domain = New Uri("http://192.168.254.164:8080/App/RestfulService").Host
     httpWebRequest.CookieContainer = New Net.CookieContainer
     httpWebRequest.CookieContainer.Add(cookie)
 End If

 httpWebRequest.ContentType = "application/x-www-form-urlencoded"

 Dim postData As Byte() = New System.Text.UTF8Encoding(False).GetBytes(RichTextBox1.Text)

 httpWebRequest.ContentLength = postData.Length

 Using tmpStream As IO.Stream = httpWebRequest.GetRequestStream
     tmpStream.Write(postData, 0, postData.Length)
 End Using

 Dim httpWebResponse As Net.HttpWebResponse = CType(httpWebRequest.GetResponse, Net.HttpWebResponse)

 If WebValidation.WebResponseHasContent(httpWebResponse) Then

     Dim str As String = String.Empty
     'Read the raw HTML from the request
     Using sr As New IO.StreamReader(httpWebResponse.GetResponseStream, System.Text.Encoding.UTF8)
         str = sr.ReadToEnd
     End Using

 End If

Return str

So, is this a cross-domain cookie request? and how can I recreate this functionality in my web client?

Mr Shoubs
  • 14,629
  • 17
  • 68
  • 107
  • If any type of cross domain cookie were possible, wouldn't that be a huge security flaw? – j08691 May 01 '12 at 15:53
  • Is your webserver on the same internal network as the 3rd party system it is trying to call? – edralph May 01 '12 at 15:56
  • @edr - no, our web server is on the internet, the 3rd party server is behind the customers firewall and is not accessible. In my dev scenario, they are both in the same office. – Mr Shoubs May 01 '12 at 15:58
  • when you go to deploy this to production and your webserver is in the outside world and 3rd party app is inside the firewall, how is it going to work? If the 3rd party is accessed via the client as you are trying to do then these requests will come from different IPs and it'll be difficult to open up a rule in the firewall to allow access (other than making it public access). Hopefully you've got a plan. – edralph May 02 '12 at 07:31
  • The answer is here: http://stackoverflow.com/a/10353875. The web client sites in the middle and uses jQuery to post httprequests to the other server, – Mr Shoubs May 02 '12 at 08:49

2 Answers2

1

I don't think you are trying to set a cross domain cookie. A system wouldn't ask you for that. Usually in a situation like this you need to do some handshake with the 3rd party system to get a token or in your case a JSESSIONID first (from the system). However from the looks of things you are trying to set a cookie on the 3rd party system rather than accepting a cookie from the system. Does that make sense? So what I'd expect is that you need to make a request through to the 3rd party system to get hold of the token and then to pass that token back for every subsequent request when you are trying to grab the xml.

I think that in your scenario you have your web-app and the 3rd party app. What you might be confusing is cookies being set on your browser vs cookies being 'set' on your web-app (for authentication purposes).

When you have authenticated with the 3rd party system and you get a JSESSIONID back, try setting your subsequent request headers to contain a 'cookie' header containing the JSESSIONID or whatever it is that the 3rd party system needs for authentication.

Remember that in this case where you are calling the 3rd party as a service from your web-app, it's your web-app that is the 'browser' for that call to the 3rd party. So when it makes subsequent calls to the 3rd party system it has to mimick a browser by pretending that a cookie (containing your authentication sessionid) is there - you do this by setting the 'cookie' request header.

edralph
  • 1,831
  • 1
  • 14
  • 14
  • What you are saying makes sense. How can I set my subsequent request headers to contain a 'cookie' header containing the JSESSIONID ? (I assumed the browser would take care of this automatically and when it didn't, thats when I went down the route of setting it) – Mr Shoubs May 01 '12 at 16:19
  • The interaction is between your web-app and the 3rd party system, your browser only interacts with your web-app. So as far as the 3rd party is concerned, the web-app is the browser. So if the 3rd party app needs a cookie with the right sessionid, you have to craft that yourself by creating a request header. What is your web-app coded in? – edralph May 01 '12 at 16:25
  • ...jQuery, jQuery Mobile and HTML. I don't have any server side code that affects this. – Mr Shoubs May 01 '12 at 16:26
  • pretty sure you can set request headers (and therefore cookies) using jQuery - have you looked at the documentation? – edralph May 01 '12 at 16:31
  • I think you can using this - http://api.jquery.com/jQuery.ajax/ however I'm not sure how to use it to set a cookie I've recieved on a previous request. – Mr Shoubs May 01 '12 at 16:33
  • accepted as you set me on the right path - I've asked how to do the above in another question, (http://stackoverflow.com/q/10401056/198048) – Mr Shoubs May 01 '12 at 16:44
  • eep ok - if you're doing this client-side then the ajax request is going to come from your browser isn't it. If you were doing this server-side you'd be able to grab the sessionid from the 3rd party call and store it in session for subsequent requests. Doing this client-side is a little trickier! – edralph May 01 '12 at 16:56
-2

You can't. Browser makers have spend a lot of time & effort to ensure that what you're trying to accomplish can't happen, and even if you did find a temporary solution, it would be considered a security hole & probably patched in the next release.

Instead, try to figure out how to pass the information needed into the web service.

chris
  • 36,094
  • 53
  • 157
  • 237
  • The 3rd party has specified that they must be sent the cookie. Please can you confirm that I am trying to set a cross domain cookie? - the server does send one to me in the response. – Mr Shoubs May 01 '12 at 15:57
  • It sounds like you need to authenticate to the web service before you can use it. You'll need to figure out what they need in order to authenticate. – chris May 01 '12 at 16:09
  • I am already authenticated, I call their login method which returns an object that has various properties, one of which is success, the other is the session id. In the response header I also get Set-Cookie JSESSIONID=8f7ea58cfc0bb0fba86ec2b1f668; Path=/SubFolderName. In my windows client if I don't attach the cookie for following calls I get the unauth response. This is defiantly a problem with the cookie, not authentication with the web service. – Mr Shoubs May 01 '12 at 16:11