NET 4.5 HttpClient send cookie anyway (despite changed domain) - cookies

I have created an HttpClient in C#
Client = new HttpClient(handler);
The handler is this
var handler = new HttpClientHandler
{
CookieContainer = CookieContainer,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
I send some requests in a site, let's say it is xyzevents.com. I receive my responses normally, I store some cookies I receive from "Set Cookie:*" commands, everything works good.
However, after this I try to communicate with the site xyz.com. In order to do that, I must send my requests, using the cookies I stored from xyzevents.com earlier. The HttpClient can't do that, because it sees the host is different than xyzevents.com.
Is there a way to bypass that check, and send my requests with no problem?

I don't think there's anyway to "disable" this check. I think it's the HttpClient that ends up deciding which cookies should be sent, not the container. And in the end, the security risks that could happen by sending random cookies anywhere are pretty large.
With that, you could easily loop through all the cookies received from xyz.com, create them manually with the domain changed but the same values. Then add them to a new collection which is sent to xyzevents.com.

Related

send a cookie with XMLHTTPRequest (TVMLJS)

I am developing an application for my AppleTV. The App will read movies from an online website that hasn't developed any API for this kind of thing.
I use XMLHTTPRequest to get the different URLs and have the user search for his movie, etc... Everything is working fine, except for a single request. To get the movie URL, I have to send a get request to a specific address (let's say http://example.com/getmovie.html) with a constant cookie (let's say mycookie=cookie).
I've tried using setRequestHeader:
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', 'mycookie=cookie');
xhr.send();
But no cookie seems to be sent.
I also tried setting the cookie with Document.cookie like I would have probably done in a "normal" js script (running in my browser) but no luck either.
This is extremely frustrating, especially since I'm stuck so close to the end of my app.
I guess cross-origin might be the issue but I'm able to get URLs without issues if I don't have to set cookies, so I am a bit lost there.
Please let me know how I can get http://example.com/getmovie.html with a specific cookie header.
Thanks for your help
im sorry to inform you but the xmlHTTPRequest function of javascript does not allow a cookie header to be set for security reasons as shown here: Why cookies and set-cookie headers can't be set while making xmlhttprequest using setRequestHeader? the best way i could see you making that get request would be to a proxy server that you would be running. I believe that it is built this way to prevent you from setting cookies on domains that you do not own, furthermore i do not see an alternate resolution to this problem as no were in the docs i looked at was cookie persistence or management mentioned
In case someone has the same issue:
I didn't find a solution to sending a cookie with javascript. However, in my situation, the origin of the request didn't matter, only the cookie did. My solution was then to create a PHP file receiving the destination URL and the cookie content as parameters, and then sending the get request with the cookie as a request header. (more information about how to do so here: PHP GET Request, sending headers).
In my javascript I then use XMLHttpRequest to connect to my PHP file (hosted online) with simple get parameters and I then receive the response from the PHP. That trick of course won't work if the origin of the request matters (except if you host your file at home I guess, but in my case I want my application to work even if my WAMP isn't on).
Well... the problem here is the line xhr.setRequestHeader('Cookie', 'mycookie=cookie'); line just because the 'Cookie' header is reserved for the client browser to send the stored cookies. This means you are trying to do what the browser already does. When you send a any request, the client browser automatlycally will take all the cookies related to the site you are requesting and put them on the 'Cookie' header, you don't need to do anything else, if your cookie exist in your browser, it will be send.
Cordova how to send session cookie, allow credentials with XMLhttprequest:
// JS
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/ajax.php', true);
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
// alert(xhr.responseText);
// Get header from php server request if you want for something
var cookie = xhr.getResponseHeader("Cookie");
// alert("Cookie: " + cookie);
}
}
xhr.send();
// Php
// You can add cookie to header and get with (session works without it)
header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');

Stub generated using Axis2 Webservice forming new connection for redirect URL...Need same TCP connection...!

I am badly stuck with a SOAP based integration using Axis2 framework for generation of client stubs from the Server WSDL. The scenario is as follows :
There is always a login API call first, which gives a Success response in SOAP body and Temporary Redirect in HTTP header. Also provides a URL which contains the session ID in the Location field of HTTP Header.
The next API call is required to be made at this redirect location. IN THE SAME TCP CONNECTION, for getting a proper response.
Now, the problem is, as a part of Webservice implementation using Axis2 generated stubs, I need to reload this redirect URL and re-instantiate it as --- "stub=new Stub(newurl)"
As soon as this is done, it creates a new TCP connection and so, the next request gives the response as "session ID invalid" because it goes out-of-sync with login API.
I have tried everything mentioned as a solution in this forum and nothing is working out.
For e.g --
MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
HttpClient httpClient = new HttpClient(httpConnectionManager);
ServiceClient serviceClient = stub._getServiceClient();
Options opts = stub._getServiceClient().getOptions();
opts.setTo(new EndpointReference(prop.getProperty("target_end_point_url")));
opts.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE);
opts.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
serviceClient.setOptions(opts);
stub._setServiceClient(serviceClient);
Similarly, I have tried many other options too. But it's not helpful at all.
Faced exactly the same issue.
Following steps solved the issue.
1. Using HttpClient, perform login. Don't use stub object to perform login.
2. Use the Location Header URL, to create new stub object i.e. stub = new Stub(locationURL). (Your existing options setting should be retained.)
3. There is a default timeout, by which server disconnects the TCP connection. In my case it was 50 seconds. Hence as soon as i performed login in step 1, i execute a timer every 40 seconds, to send an empty requests to new Location URL using HeadMethod of same HttpClient object.

How do I capture (in Fiddler) the HTTP requests issued by Nancy.Testing.Browser

I have the following NancyFX unit test.
var browser = new Browser(new UnitTestBootstrapper());
var response = browser.Post("/login", with =>
{
with.FormValue("UserName", userName);
with.FormValue("Password", password);
});
response.ShouldHaveRedirectedTo("/home");
You can see that I use an instance of Nancy.Testing.Browser to POST some form values. I would like to capture this Http request in Fiddler but I am not sure how to set-up the Browser (a proxy perhaps?)
Thanks
You can't because they never hit the network; that's the whole point of the browser class - to give you end to end testing without the performance hit/configuration issues of having to use hosting/http/networking/browser rendering.
If you want to go via the networking stack then use something like Selenium, or spin up a self host and poke it with EasyHttp or manually with HttpClient.

Cookie handling in subsequent requests in same page

I'm creating my own (multi threaded) ISAPI based website in C++ and I'm trying to implement correct session management.
The problem is that when a new session should be created, the session is created twice when using subsequent requests in the generated web page.
Here's how it works:
- Client requests http://localhost and sends either no cookie or a cookie with an old session ID in it.
- Server looks at the session cookie and feels that it needs to create a new one because it no longer exists: it prepares a header with a cookie in it with a new session ID and sends the complete header to the client (I tracked this with http live headers plugin in firefox and it is correct). It also prepares some data like the page and and stuff like that (not yet body data, as it is still processing data from the database and stuff like that) and sends what it has back to the client.
- Client should have this new session cookie now, and sees the stylesheet link and immediately sends the stylesheet request http://localhost/css to my server. But... he still does this with the old session ID for some reason, not with the newly received one!
- Server sees this request (with again an no longer existing session id), generates another new session and sends the new session id with a cookie along with the stylesheet data.
So the client has received two session id's now and will from now on keep using the second one as the first one is overwritten, but nevertheless the first page has used the wrong session (or actually, the second page has).
You could say that this is not a problem, but when I start using personalized stylesheets, I will have the wrong stylesheet on the first page and as the page will use AJAX to refresh the content (if available), it is possible that the stylesheet is never reloaded unless the client refreshes.
So, is this a problem that is always there when doing this kind of thing? Will the browser always send an old cookie although it has already received a new one but is still processing the page? Is this a problem that, for example PHP, also has?
Note: before all the discussions start about "use php instead" or something: I am rewriting a website that I had first written in PHP, it became popular, had thousands of (real) visitors every hour and started killing my server (the website doesn't make that kind of money that I can throw lots of servers at it). By writing it in C++, requests take 2ms instead of 200ms in PHP... I can optimize everything. By taking my time to develop this ISAPI correctly, it is safely multi-threaded and can be multi-processed, multi-servered. And most of all, I like the challenge.
Added note: It seems that the problem is only there when an old session exists in the cookies, because when I completely clear all cookies from my browser, and a new one is created and sent back to the client, the subsequent stylesheet request immediately uses the given session id. This seems to be some kind of proof that I'm doing something wrong when an old session id is sent... Should an existing cookie be deleted first? How?
Added note: The cookie is written with an expire-date one year ahead.
I have found out what the problem was, I was in the assumption that setting a cookie without specifying a path would result in making the session work on all paths on that domain.
By using http://foo.bar/home as main page and http://foo.bar/home/css as stylesheet, internally translating that url to ?s1=home and ?s1=home&css=y, I was actually using two different paths according to the browser which did not pass the cookie to the css-request.
For some reason, they actually got together afterwards, I don't fully understand why.
Isn't this silly? Will people not often have a http://foo.bar/index.php and a http://foo.bar/css/style.css.php , just because they use subdirectories to keep their structure clean?
If anyone knows of a way to fix it, to make subpaths also work with the same cookies, let me know, but as I understand it from the definition of cookies, they are stuck within a specific path (although, it seems that if you specifically add a path other than /, it will work on subdirectories as well?)

Jetty 8 WebSocket and Session

im building a little web app that uses jetty 8 as server and websockets.
On client (browser) side: the user opens with his browser my index.html and that opens and establishes a new WebSocket connection with my jetty server.
On server side, i have a WebSocketServlet that listens on incomming WebSocket connection.
#Override
public WebSocket doWebSocketConnect(HttpServletRequest request, String arg1) {
System.out.println("doWebSocketConnect");
System.out.println("WebSocket "+request.getSession().getId());
return new UserWebSocket(request.getSession());
}
UserWebSocket is a class that implements jetty's WebSocket.OnTextMessage interface for receiving and sending messages via websockets.
So far so good, everything works fine so far.
So what i now want to do, is to work with HttpSession to identify the current user, because
the index.html site can also do some ajax calls on other (non WebSocket) Servlets, like submit some simple form data via HTTP POST etc.
For example have a look at my SearchServlet:
public class SearchServlet extends HttpServlet{
...
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(request.getSession());
}
...
}
My problem is, that this two servlets (WebSocketServlet and SearchServlet) have two diffrent HttpSession object with two diffrent HttpSession ids:
for exmaple my WebSocketServlet have got the session id = 1dwp0u93ght5w1bcr12cl2l8gp on doWebSocketConnect() and the SearchServlet got the session id = 1sbglzngkivtf738w81a957pp, but the user is still in the same browser and on the same page (index.html) and have not reloaded the page etc. The time between establishing a WebSocket connection and the SearchServlet call is just a few seconds ...
Any suggestions?
EDIT: btw.
Both Servlets are in the same ServletContext:
ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContext.setContextPath("/servlets");
servletContext.addServlet(new ServletHolder( new MyWebSocketServlet()),"/liveCommunication");
servletContext.addServlet(new ServletHolder( new SearchServlet()),"/search");
There are two possible causes that I can see.
1 - Your server is not correctly configured. Since you haven't provided the details about how you're running Jetty, and how you've configured it, it's certainly possible that you've introduced a problem there.
2 - It's actually a timing issue.
I assume your index.html is static content, so it doesn't create a session on its own.
Within the index.html there is some javascript that will launch two separate requests. One as a WebSocket, the other as an XMLHttpRequest (AJAX). Since the 2 requests are launched simultaneously, they have the same set of cookies - which in this case is none.
In each case, since the request provides no cookies, the server must generate a new HTTP Session. There server does not know that the two requests are from the same client, so 2 separate HTTP sessions are created.
If that's the case, then you could fix it quite simply by putting a filter in front of the index.html, that forces the creation of the session.