CookieContainer does not store cookies for internationalized domain names - c#

I'm trying to perform authorization on a cyrillic domain using WebClient. Authorization goes through few stages with redirects between normal and punicode domains. The problem is HttpWebRequest can not store cookies in assigned CookieContaier if it was set by punycode domain.
For example, this code will throw CookieException.
var cookie = new Cookie("test_cookie", "test_value", "/", ".xn----7sbcca6bi0ak9b0a6f.xn--p1ai");
var container = new CookieContainer().Add(cookie);
The problem is exacerbated by the fact that response that sets cookie redirects to another page, i.e. after WebClient.UploadValues(...) have been executed there's no cookie information in WebClient.ResponseHeaders.
Below is normal authorization process (using browser)
Method Result Received Type URL RedirectURL Set-Cookie
POST 302 1,18 K text/html http://xn----7sbcca6bi0ak9b0a6f.xn--p1ai/admin/login http://xn----7sbcca6bi0ak9b0a6f.xn--p1ai/admin sess_id=.......; expires=Mon, 06-Jun-2016 07:20:57 GMT; Max-Age=31536000; path=/; domain=.xn----7sbcca6bi0ak9b0a6f.xn--p1ai; httponly
GET 302 722 text/html http://xn----7sbcca6bi0ak9b0a6f.xn--p1ai/admin /admin/orders
GET 200 200,00 K text/html http://xn----7sbcca6bi0ak9b0a6f.xn--p1ai/admin/orders
Is there any workaround?

Are you sure the IDN is the problem?
The following code snippet (which is the same as yours, but with the second line split up to make it compile)
var cookie = new Cookie("test_cookie", "test_value", "/", ".xn----7sbcca6bi0ak9b0a6f.xn--p1ai");
var container = new CookieContainer();
container.Add(cookie);
container.GetCookies(new Uri("http://test.xn----7sbcca6bi0ak9b0a6f.xn--p1ai")).Dump();
does not throw a CookieException at all (run from LINQPad). Could the problem perhaps be in the name and/or value you are trying to set for the cookie? What is the exact message you get from the CookieException?

Related

HttpWebRequest cookie for redirected request

In my program I should authorize on the site, get authorization cookie value and send request to page (page1, which url like "mysite.com/lots/8188/request/4261/"), which redirect me to another (page2, which url like "mysite.com/lots/view/8188/"):
sendingRequest.CookieContainer = new CookieContainer();
sendingRequest.CookieContainer.Add(sendingRequest.RequestUri, new Cookie(ASPNETSessionIdCookieName, this.ASPNETSessionIdCookie));
sendingRequest.AllowAutoRedirect = true;
sendingRequest.MaximumAutomaticRedirections = 100;
HttpWebResponse response = (HttpWebResponse)sendingRequest.GetResponse();
Ok, page1 return me expected HTTP 302 Page with expected url of page2, then sendingRequest go to page2, but it don't send ASPNETSessionIdCookieName cookie to page2 and server return me uncorrect response.
How can I use "ASPNETSessionIdCookieName" for redirected request?
The auto-redireciton will follow the cookies domain/URI to check if the cookies should be sent again, once the URL is changing I believe the problem is the first parameter of the CookieContainer.Add.
You're restricting the cookie to the first page URL.
Try change for something like this:
sendingRequest.CookieContainer.Add(new Cookie(ASPNETSessionIdCookieName, this.ASPNETSessionIdCookie));
If you want to restrict the cookie only to that domain you can them use Cookie four parameters constructor.

Get mutliple Cookie in Headers C#

From Fiddler , I can see the Cookie in Request Header
However, when I tried to parse the Cookie in C# by webresponse HTTP,
var webResponse = (HttpWebResponse)WebRequestBuilder
.GetRequest(new Uri(url))
.AllowAutoRedirect(false)
.GetResponse();
var test = webResponse.Headers;
in the test, which is returned the headers containing the Set-Cookie, what I get is just :
ASP.NET_SessionId=nod1bi3znubfdf55fzre2hye; path=/;
HttpOnly,host=SCANDICWEB203; path=/; HttpOnly,ieAlertDisplay=true;
path=/,scandic_lb_cookie=1733559050.0.0000; path=/
Not all of the Cookies were returned like evar58,s_sv_sid, scandic_lb_cookie.... I need all of them in order to push those cookies to execute another url.
So what I have to do to get all the cookie from request header like Fiddler in C#?

JsonServiceClient not using cookie placed in cookiecontainer

I've posted a couple of questions previously to get where I am now:
Reconnecting to Servicestack session in an asp.net MVC4 application
and
nullreference exception when adding session cookie to ServiceStack
Quick background on the app: This is an asp.net MVC application accessing data on a remote servicestack installation.
At this point I am successfully authenticating with SS, saving the session key in a cookie, and inserting that cookie into the CookieContainer of a new JsonServiceClient instance.
However when I try to grab some data via the new JsonServiceClient instance:
CallList = client.Get(new ServiceCallRequest()).Result;
The remote ServiceStack instance seems to be redirecting me to the default ASP login area (/Auth/login or something similar). This redirect in itself isn't a problem, but it does seem to indicate that the client isn't using the SS session already established on the remote machine.
This is the code that is actually inserting the cookie into the client cookie container and calling for a list of objects:
public List<ServiceCallModel> LoadList()
{
try
{
var cookie = HttpContext.Request.Cookies.Get(SessionFeature.PermanentSessionId);
var client = new JsonServiceClient([api address]);
cookie.Domain = ".domain.com";
var cookie1 = new Cookie(SessionFeature.PermanentSessionId, cookie.Value);
cookie1.Domain = ".domain.com";
client.CookieContainer.Add(cookie1);
List<ServiceCallModel> CallList = new List<ServiceCallModel>();
CallList = client.Get(new ServiceCallRequest()).Result;
return CallList;
}
catch (Exception ex)
{
return new List<ServiceCallModel>();
}
}
I can verify that this remote resource works with a monotouch Android application using the C# client. The only difference of course is that the Android client is persistent; the one in question here isn't.
The above example always returns a WebServiceException ("Not Found") (Which I assume is actually a 401/403 that has been redirected annoyingly by ASP).
Does this seem reasonable, or am I missing/misunderstanding some functionality of the JsonServiceClient/ServiceStack?
Thanks much
Update
Using Fiddler, I can confirm that the cookie is being stored in the browser and sent back to the MVC application in the request header:
GET / HTTP/1.1
Host: [web app address]
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: ASP.NET_SessionId=3457C511FECBECCD3C055C21;.MONOAUTH=PzE6iBuLIbv1evgACfpUwpC1D7opCANroPDQN/mXHNvGAgkjqq04Tdd8EnnGTL7y3lWYWY4+GWaXGDT0Fm7+eJxRdpy LJMaUQ6BiYmb3dxRi1B3f/qkmPMbFIoC7vC9M; ss-pid=lzJ+o9vG/7F3YZ9JNN2F
At this point I am trying to find out of that same ss-pid value is then making it back to the API server in a request header.
Update 2
Using tcpdump I was able to see that the ss-pid value is in fact making it all the way back to the API server (The "remote servicestack instance"). So now I think I need to troubleshoot that, not the client. Any thoughts?
Snippet of tcpdump output:
0x0090: 6e65 740d 0a43 6f6f 6b69 653a 2073 732d net..Cookie:.ss-
0x00a0: 7069 643d 6c7a 4a2b 6f39 7647 2f37 4633 pid=lzJ+o9vG/7F3
0x00b0: 595a 394a 4e4e 3246 0d0a 4163 6365 7074 YZ9JNN2F..Accept
I know that the ss-pid values are different in each part of this post. They were obtained at different times
Update 3
I've also changed the LogFormat in the vhost config file to spit out the value for the cookie called "ss-pid" (At the end of the log entry).
The resulting logs on the ServiceStack remote API server looks like this:
172.16.0.17 - - [08/Oct/2013:12:26:52 -0400] "GET /sc/0 HTTP/1.1" 500 3082 "-" "-" "HFMtFpPQkpE0Br6/fEFg"
172.16.0.17 - - [08/Oct/2013:12:27:06 -0400] "GET /sc/0 HTTP/1.1" 302 394 "-" "-" "HFMtFpPQkpE0Br6/fEFg"
172.16.0.17 - - [08/Oct/2013:12:27:07 -0400] "GET /login.aspx?ReturnUrl=%2fsc%2f0 HTTP/1.1" 404 451 "-" "-" "HFMtFpPQkpE0Br6/fEFg"
This "500" status on the first request sticks out. I will be investigating this now.
Update 4
The 500 status seems to be a case of Microsoft.Web.Infrastructure.dll being included in the bin directory. Deleted that to resolve the 500 response, but this did not fix the overall problem.
ServiceStack places two Session cookies in the Request, 'ss-id' and 'ss-pid'. This line in your code...
var cookie = HttpContext.Request.Cookies.Get(SessionFeature.PermanentSessionId);
will grab the 'ss-pid' cookie. But, you probably want the grab the 'ss-id' cookie which is the cookie for your current authenticated session.
var cookie = HttpContext.Request.Cookies.Get(SessionFeature.SessionId);
Take a look here for more information on ServiceStack Sessions.

CookieContainer returns empty

Hello Everyone i have the follow code
Uri site = new Uri("http://www.receita.fazenda.gov.br/pessoajuridica/cnpj/cnpjreva/Cnpjreva_Solicitacao2.asp");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(site);
CookieContainer cookies = new CookieContainer();
request.CookieContainer = cookies;
//Console.WriteLine(cookies.GetCookieHeader(site));
//Get the response and print out the cookies again
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Console.WriteLine(cookies.GetCookieHeader(site));
}
Console.Write("end");
Console.ReadKey();
Well this code returns the Cookie OK but if i change the URI to http://www8.receita.fazenda.gov.br/SimplesNacional/Aplicacoes/ATBHE/ConsultaOptantes.app/ConsultarOpcao.aspx it's not show correctly it's return empty
Anyone can help me to solve this problem ?
The server at the new URL does not attempt to set any cookies, so of course no cookies are in the container. Modify your ASP code to set a cookie and it will work.
Add the following to your cookie: , domain=.receita.fazenda.gov.br. This says that your cookie can be used with any sub-domain of receita.fazenda.gov.br. Have a look at the RFC on cookies or use this Wikipedia article.
UPDATE: Re-reading your OP, there may be a few things that could be going awry.
One thing is that the site is not setting a cookie when making a request for www8.receita.fazenda.gov.br (as mentioned by others). Or, the site did not set the domain field of the cookie sent with the response for the request to www.receita.fazenda.gov.br. I think it's likely the former—the cookie is not being set by the web server when the request is being made.
Another thing is perhaps you forgot to request the cookie header for the correct site?? Above, you have a line of code that reads Console.WriteLine(cookies.GetCookieHeader(site));, where site is hardcoded to a System.Uri that is different from www8.receita.fazenda.gov.br. If that's the case, then you are requesting cookies for a different site than the one for which the request was made.

How to parse HttpWebResponse.Headers.Keys for a Set-Cookie session id returned

I'm trying to create an HttpWebRequest/HttpWebResponse session with an ASP.NET website to later parse an HTML form through url params (this part I know how to do), but I do not understand how to parse and set a cookie such as the session id. In Fiddler, it shows that the ASP.NET Session ID is returned through Set-Cookie in the response to the request to the / path of the url, but how can I extract this session id and set it as a cookie for the next HttpWebRequest? I understand that this Set-Cookie header would be found in HttpWebResponse.Headers.Keys, but is there a direct path to parsing it? Thanks!
The .NET framework will manage cookies for you. You don't have to concern yourself with parsing the cookie information out of the headers or adding a cookie header to your requests.
To store and send your session ID, use the Cookie and CookieContainer classes to store them and then make sure you send your cookies with every request.
The following example shows how to do this. The CookieContainer, 'cookieJar' can be shared across multiple domains and requests. Once you add it to a request object, the reference to it will also be added to the response object when the response is returned.
CookieContainer cookieJar = new CookieContainer();
var request = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com");
request.CookieContainer = cookieJar;
var response = request.GetResponse();
foreach (Cookie c in cookieJar.GetCookies(request.RequestUri))
{
Console.WriteLine("Cookie['" + c.Name + "']: " + c.Value);
}
The output of this code will be:
Cookie['PREF']: ID=59e9a22a8cac2435:TM=1246226400:LM=1246226400:S=tvWTnbBhK4N7Tlpu
The answer from Dan Herbert helped me really. I appreciate your help.
Just want to post my usage - hope it helps some one at some point of time. My requirement is that I need to send back cookies from first http post response to second http post request.
1st:
CookieContainer cookieJar = new CookieContainer();
request.CookieContainer = cookieJar;
....
CookieCollection setCookies = cookieJar.GetCookies(request.RequestUri);
2nd:
CookieContainer cc = new CookieContainer();
cc.Add(setCookies);
request.CookieContainer = cc;
I have the same problem (with amazon)
I use the following regexp:
string regexp = "(?<name>[^=]+)=(?<val>[^;]+)[^,]+,?";);MatchCollection myMatchCollection = Regex.Matches(cookiesStr, regexp);foreach (Match myMatch in myMatchCollection) { string cookieName = myMatch.Groups["name"].ToString(); string cookieVal = myMatch.Groups["val"].ToString(); Cookie cookie = new Cookie(cookieName, cookieVal); cookies.Add(cookie); }
Note that I only care about the cookie name/value...
good luck
Elia
hum I may be wrong but from what I am observing lately
Cookies from a first response, don't include the 'set cookie' as cookies that come in the header (for example some session id...) in the case of a 302 (redirect) status
If the autofollowredirect is set to true, then the set cookie are processed, and the subsequent request which is done automatically, will include those cookies defined by set cookie on the first call
If autofollowredirect is set to false then the first request doesn't get the cookies positionned by the set cookie, and I guess and this is also my queston if anyone know, that the only way to subsequently have those cookies in next request, is parse the set cookies ?

Categories