HttpCookie.Path and mapped urls - c#

According to the official documentation page HttpCookie.Path :
The Path property extends the Domain property to completely describe the specific URL to which the cookie applies. For example, in the URL http:/www.microsoft.com/asp, the domain is www.microsoft.com and the path is /asp.
and then they provide an example: MyCookie.Path = "/asp";
The previous statements in my opinion create more questions than answers.
So my question is what happens if i set the cookie like the previous example and i have a mapped route like /asp/{id}? Will work either?
Also will affect if i define the path without the / just with asp?
And one more question, what's the scope of the previous setting (i mean from what urls i can read the cookie)?

I found the answer on another official page in small letters they write:
The path can either be a physical path under the site root or a virtual root. The effect will be that the cookie is available only to pages in the Application1 folder or virtual root. For example, if your site is called www.contoso.com, the cookie created in the previous example will be available to pages with the path http://www.contoso.com/Application1/ and to any pages beneath that folder. However, the cookie will not be available to pages in other applications such as http://www.contoso.com/Application2/ or just http://www.contoso.com/.
Example:
HttpCookie appCookie = new HttpCookie("AppCookie");
appCookie.Value = "written " + DateTime.Now.ToString();
appCookie.Expires = DateTime.Now.AddDays(1);
appCookie.Path = "/Application1";
Response.Cookies.Add(appCookie);
They also talk about something similar Domain scope:
By default, cookies are associated with a specific domain. For example, if your site is www.contoso.com, the cookies you write are sent to the server when users request any page from that site. (This might not include cookies with a specific path value.) If your site has subdomains—for example, contoso.com, sales.contoso.com, and support.contoso.com—then you can associate cookies with a specific subdomain. To do so, set the cookie's Domain property, as in this example:
Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "support.contoso.com";
When the domain is set in this way, the cookie will be available only to pages in the specified subdomain. You can also use the Domain property to create a cookie that can be shared among multiple subdomains, as shown in the following example:
//The cookie will then be available to the primary domain as well as to sales.contoso.com and support.contoso.com domains.
Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "contoso.com";

I have change cookie path with following code. Hope it will work for you also.
System.Web.HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId") { Path = "/Application", Value = newID });

Related

How to exclude a site which comes under a specific domain in a cookie c#

We have a set cookie for a domain as .example.com and we have below sites which comes under this domain.
login.example.com
articles.example.com
fitness.example.com
HP.example.com
media.example.com
As, we have set the domain globally and will cover all the sites. But, i dont want to set cookie for the last site i.e. media.example.com
I have tried to set a domain as a site URL but it is not working as all the sites must share the cookies except the last one.
Expected
I don't want a cookie to be shared with media.example.com and shared with the other sites.
To not set cookies for media.example.com I would do it like that:
If you set the cookies in an aspx.cs file:
string sHost = Request.Url.ToString();
if (!sHost.StartsWith("https://media.example.com"))
{
//Write the code to set the cookies
}
If you set the cookies in a class file:
string sHost = HttpContext.Current.Request.Url.ToString();
if (!sHost.StartsWith("https://media.example.com"))
{
//Write the code to set the cookies
}
If you wouldn't use https then replace that with http.
I hope this answers your question.

Write cookies from subdomain and read from another subdomain without changing web.config

I have a simple question. I have two different projects like
http://login.mydomain.com
and
http://test.mydomain.com
. As it's name suggests, I login from login project and response redirect to test project.
I am able to create cookie for login.mydomain.com but I can not read it from test.mydoamin.com.
My question is can I create cookie from login.mydomain.com to www.mydomain.com and read it from test.mydomain.com as if I am reading it from www.mydomain.com.
This is how I create my cookies.
Response.Cookies["UserValidForMyDomain"].Value = myvalue;
Response.Cookies["UserValidForMyDomain"].Expires = dtExpireDate;
and how I read them.
string myValue = Request.Cookies["UserValidForMyDomain"].Value;
No, but you can create a wildcard cookie for the domain of .mydomain.com which will allow any subdomain to read/write it.
TO WRITE
HttpCookie hc = new HttpCookie("key", "value");
hc.Domain = ".mydomain.com";
hc.Expires = DateTime.Now.AddMonths(3);
HttpContext.Current.Response.Cookies.Add(hc);
TO READ
HttpContext.Current.Request.Cookies["key"].Value
In php this will do session_set_cookie_params
In asp and equivalent, these stackoverflow thread might be usefull
How to share session among Multiple Domains on single asp.net website?
How can you keep a session across multiple subdomains in c# mvc?

Cookie persistence and best practice

In our application there are two types of user, let's call them Alpha and Beta users. Each of these users sees a different type of toolbar / menu.
We have decided to track this using cookies. The majority of our pages are either Alpha pages or Beta pages and then there are some common pages that Alpha and Beta users share. So in each view of our application where we know the user type (Alpha or Beta) we have the following code:
HttpCookie isAlphaCookie = new HttpCookie("IsAlpha", "false"); // or true
HttpCookie isBetaCookie = new HttpCookie("IsBeta", "true"); // or false
isAlphaCookie.Expires = DateTime.MaxValue;
isBetaCookie.Expires = DateTime.MaxValue;
Response.Cookies.Add(isAlphaCookie);
Response.Cookies.Add(isBetaCookie);
The idea is then, in common pages, we don't set any cookie and rely on the previously set cookie to determine which toolbar to load. So, these two cookies are set to true or false as above in our known pages before we read them in the controller method which loads our toolbar like so:
HeaderViewModel header = new HeaderViewModel
{
FirstName = UserProfile.CurrentUser.FirstName,
LastName = UserProfile.CurrentUser.LastName,
ImageUrl = null,
OrganisationName = UserProfile.CurrentUser.OrganisationName,
OrganisationUrl = UserProfile.CurrentUser.OrganisationUrl,
ShowAlphaToolbar = bool.Parse(Request.Cookies["IsAlpha"].Value),
ShowBetaToolbar = bool.Parse(Request.Cookies["IsBeta"].Value),
ShowPublicToolbar = false
};
return PartialView("Common/_Header", header);
From reading up on how to read / write cookies this seems to be the right approach; writing the cookie to the Response object and reading the cookie from the Request object.
The problem I'm having is that when i get to the controller method that loads the toolbar the values of the IsAlpha and IsBeta cookies are both empty strings and this breaks the application.
I have confirmed that the cookies are set in the Response before they are read in the Request.
I'm wondering whether I'm missing something fundamental here.
I only expect your assumption " in common pages, we don't set any cookie and rely on the previously set cookie to determine which toolbar to load" to work if you are calling these partial actions, which you referring to as "common pages" I guess, through Ajax Calls. If you are using
#Html.RenderAction('nameOfaAtion')
then I don't think what you have in place will work.
Reason is Both your main action and partial actions are executed within the same Http Request Cycle so the cookies you are trying to access from the Request Object in your common pages have not yet came as part of Request.
Edit
As I can see you are hard coding the cookies on each page so Guess you can also do something like below. Not originally the way you are trying to do but I think it will do the same thing you are trying.
In your pages change the partial view call to like this.
#Html.Action("LoadHeader", "Profile", new{IsAlpha=False, IsBeta=true});
Then Change the signature of the LoadHeader action to receive these two extra parameters
public ViewAction LoadHeader(bool IsAlpha, Bool IsBeta)
Then with the viewModel Initialization change two lines as below.
ShowAlphaToolbar = IsAlpha,
ShowBetaToolbar = IsBeta,

Create cookie with cross domain

I am working on cookies. I am able to create cookies very easily. To create a cookie I am using this code:
HttpCookie aCookie = new HttpCookie("Cookie name");
aCookie.Value = "Value";
Response.Cookies.Add(aCookie);
This code is fine for me and it gives me localhost as Host. But the problem comes here when I try to add a domain name here like:
HttpCookie aCookie = new HttpCookie("Cookie name");
aCookie.Value = "Value";
aCookie.Domain = "192.168.0.11";
Response.Cookies.Add(aCookie);
Now the cookie is not generated. Any suggestions?
You can only set the domain to yourself (the current site) and sub-domains of yourself, for security reasons. You can't set cookies for arbitrary sites.
As Marc has said - you can't do this; unless the domain is a subdomain of the one returning the response.
The same limitation applies to javascript code on the client adding cookies as well - the same origin policy will apply.
A simple way to achieve this is generally to include on the page returned from abc.com somewhere a reference to a resource on the domain xyz.com - typically a javascript file or something like that.
You have to watch out there, though, because that's a third-party cookie and some users will have those disabled (because it's how ad-tracking works).
Assuming you have a known set of cookies you want to track across domains and that you own all the domains you are sharing cookies with, you can build this functionality yourself. Here is poor man's cross-domain cookie tracking:
You can add "?favoriteColor=red" to all links on abc.com that point to xyz.com.
XYZ Contact
Then do the same thing for all links on xyz.com that point to abc.com.
ABC Contact
Now on every page of abc.com and xyz.com need to check the http request path for ?favoriteColor=red and if it exists, set the favoriteColor cookie on that domain to red.
// Pseudocode
if(queryString["favoriteColor"] != null) {
setCookie("favoriteColor", queryString["favoriteColor"]);
}
Tip 1: Do some validation to ensure that the value you get is valid because users can enter anything.
Tip 2: You should be using https if you're going to do this.
Tip 3: Be sure to url escape your cookie name and value in the url.

Why do some cookies have a '.' before the domain?

Trying to share cookies accross 2 domains in asp.net, for some reason 1 domain has a '.' before the domain, and the other doesn't.
Why is that?
e.g:
.staging.example.com
and
staging.example.com
Is this something to do with how I create the cookie, or a web.config change?
I am not using forms authentication, just creating a cookie manually.
Upd
I am setting the cookie domain like:
HttpCookie c = new HttpCookie("blah");
c.Value = "123";
c.Expires = DateTime.Now.AddHours(12);
c.Domain = ".staging.example.com";
Response.Cookies.Add(c);
For some reason not getting the '.' in the cookie.
What could be the issue?
If you set a . before a domain name, e.g.
.staging.example.com
This means that any domain name that resides under that, will have access to that cookie. E.g. test01.staging.example.com would have access to whatever was in that cookie as if it had created it itself. Without the dot, its limited to the specific domain that is named.
The cookie for .staging.example.com is also readable for each subdomain of that domain, e.g. www.staging.example.com, the other one is not.
To make the cookie available on all subdomains of staging.example.com then you'd set it to .staging.example.com

Categories