HttpCookie is not deleted when session changes or is invalid - asp.net

I'm creating an HttpCookie, setting only the name and value and not the expires property, then adding it to the response. Simple enough. The cookie is created (but not persisted) as expected. The problem is when the session changes for some reason (like the website was rebuilt, or I rebuilt my app when debugging) then the cookie stays around. I want the cookie to be valid for only the original session it was created on.
According to MSDN it says: "If you do not specify an expiration limit for the cookie, the cookie is not persisted to the client computer and it expires when the user session expires."
I guess I don't know exactly what "session expires" encompasses. I figure the cookie gets deleted after 20 min when the session expires. But should the cookie get deleted if the session it was created on doesn't exist anymore for any number of reasons? The only time I've seen the cookie get deleted is when the user closes all browser windows and opens a new one.
If this is all true, I may have to store the original session id ("ASP.NET_SessionId") in the cookie, then check it against the current session id, if they're different, then delete the cookie or create a new one.
Here's the code (the only difference between my cookie and the one in the MSDN examples is I'm storing multiple values in the cookie):
private void SaveValuesToCookie(string[] names, string[] values)
{
HttpCookie cookie = new HttpCookie("MyCookie");
for (int i = 0; i < names.Length; i++)
{
string name = names[i];
cookie.Values[name] = values[i];
}
Response.Cookies.Add(cookie);
}
private string GetValueFromCookie(string name)
{
HttpCookie cookie = Request.Cookies["MyCookie"];
if (cookie == null)
return null;
return cookie.Values[name];
}

The only time I've seen the cookie get
deleted is when the user closes all
browser windows and opens a new one.
And that is exactly what MSDN means when it says the cookie will be deleted when the session expires. Unfortunately, I believe this isn't consistant across browsers anyway, so it's not much use to anyone.
You should always set an expiry date on Cookies.
If this is all true, I may have to
store the original session id
("ASP.NET_SessionId") in the cookie,
then check it against the current
session id, if they're different, then
delete the cookie or create a new one.
I hate to say it but this isn't going to help you either. The .NET Framework likes to recycle session IDs, so you can't guarantee it will be different.
Bad news out of the way, I would advise you to reconsider what you're trying to do from an architectural standpoint.
Restarting the app is something that happens entirely on the server; cookies are something that happen entirely on the client. While the client will talk to the server, it is purely a Request/Response relationship, the server cannot communicate events such as an application restart to the browser.
If you want to store a value somewhere which is only valid for the lifespan of a server session, why not store it in Session rather than in a Cookie?

I'm aware of all that, but it's not secure enough for our clients needs. The session can still get spoofed or injected. See: http://msdn.microsoft.com/en-us/magazine/cc163730.aspx#S9
Looks like I'm left to creating an expired secure cookie separate of the session, and refreshing the expiration date when I can (ie when the user accesses certain pages).

Related

.net mvc some users missing cookies

I am using custom forms authentication for an asp.net MVC application, and am having problems with some users seemingly not having cookies. The custom forms authentication method we are using is similar to this - custom forms authentication. Essentially, we create a custom Principal and Identity, serialize it, and store it in the UserData property of the FormsAuthenticationTicket :
Login
MyCustomPrincipal principal = new MyCustomPrincipal(user);
DateTime expiration = DateTime.Now.AddMinutes(30);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
u.Username,
DateTime.Now,
expiration,
true,
JsonConvert.SerializeObject(principal));
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));
cookie.Expires = expiration;
Response.Cookies.Set(cookie);
We then grab the auth cookie in the Application_AuthenticateRequest event of global.asax.
global.asax - Application_AuthenticateRequest
// Get the authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
// If the cookie can't be found, don't issue the ticket
if (authCookie == null) return;
// Get the authentication ticket and rebuild the principal
// & identity
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value);
MyCustomPrincipal userPrincipal = new MyCustomPrincipal(authTicket.UserData);
DateTime expiration = DateTime.Now.AddMinutes(30);
FormsAuthenticationTicket newAuthTicket = new FormsAuthenticationTicket(
1,
((MyCustomIdentity)userPrincipal.Identity).Username,
DateTime.Now,
expiration,
true,
JsonConvert.SerializeObject(userPrincipal));
authCookie.Value = FormsAuthentication.Encrypt(newAuthTicket);
authCookie.Expires = expiration;
HttpContext.Current.Response.Cookies.Set(authCookie);
Context.User = userPrincipal;
web.config
<authentication mode="Forms">
<forms loginUrl="~/Home/Index" timeout="29" name="MYFORMSAUTH" cookieless="UseCookies"/>
</authentication>
This works fine for the large majority of users, however, there are some users who appear to be getting no authorization cookie set. I did a few tests to add more information to my Elmah error logs to see if I could find out more about the problem.
First, I tried setting some test cookies before and after the setting of the authcookie in the Login method. These cookies did not appear in the Elmah logs, so it appears adding cookies of any kind in this method is not working. However, there are other cookies in the logs, including the ASP.NET_SessionId, a google analytics cookie, and sometimes there are even other cookies I have set at other locations in the application (probably from a previous session)
Second, I tried adding some info to the session from the login action, and including it in the error log if the authcookie was not found on the next action. I included the length of the cookie (the name's length + the encrypted value's length) as well as the time of the attempted login. Both of these are added only if the user's credentials are valid, and the application attempts to add the auth cookie. I do see these values in the error logs being produced. The length is always greater than 0, and I haven't seen any bigger that about 2300, so I don't think size is an issue. And the attempted login is identical to the time that the error occurs - so the session variables should have been set immediately before the error occurred (cookies went missing).
A few more notes -
There doesn't appear to be any browser in particular that seems to be causing the error more (though it is possible it occurs more on mobile browsers)
Again, the site seems to work for the large majority of users, and of course we cannot reproduce the issue
Since I am not seeing the test cookies, I am guessing that for some reason no cookies are being set from the login method at that time (though I can see other cookies set elswhere that would imply previous successful logins)
The http referer in the elmah logs is usually set to the login page, which implies that users are probably not hitting the offending page without logging in (at least some of the time) - the state of the session variables seems to support that assumption
I'm often seeing multiple of these errors in a row (separated by a minute or so) - implying that the issue isn't resolved with repeated login attempts (not sure why it would be)
It appears users who have this issue continue to have the issue. In other words, it doesn't appear to be "luck of the draw" - but something either with the user's account (which the cookie length session variable implies it is serializing correctly), or the client browser.
I've heard of at least one user who was able to log in on a mobile device, but not their desktop
In total the site probably uses 10 or so cookies (including all of the various test cookies that have been added) - before adding the test cookies it used about 4 including the auth cookie. Also, when the bug occurs, there appear to usually only be 2 or 3 cookies in the request, so I don't think number of cookies is an issue.
At this point I'm willing to try almost anything. I tried setting up using the custom identity stored in the session as a backup, but couldn't get that working, so even if anyone has ideas about how to implement that (if possible) it would be appreciated (if this is off topic then I can remove it).
Sorry for the walls of text, but I just wanted to point out all of the potential issues we have investigated and most likely ruled out.
EDIT
It appears there may be another potentially related issue. I'm seeing error logs which lead me to believe that the "IsAuthenticated" attribute of some Identities is being set to false when it should not be. We do initialize this to false, and set it to true after the user answers a security question. When we set it to true, it should update the principle and the authentication ticket / cookie. I'm not sure if this is happening because of some issue with how I am deserializing the custom principal or not.
is server side caching enabled?
is I remember exactly I had similar problem and the cause was the server side caching (misconfigured) and the server side code was not executed but the client reaches the page.
in addition in my side there was a bug (iis bug on caching enabled on dynamic page) that in some situations the session cookie is sent to more than 1 client and this causes unexpected result.
this can explain your non logging behavior and the cookie not present on client.
Regards
So I've sort of given up and decided to use the Session to store my principal, and check it when I don't see the authentication cookie. I can do this somewhat easily by creating a custom Authorize attribute, and checking the session there. I haven't pushed this to production yet, so I'm not 100% sure this will work around the issue, but preliminary testing would suggest it will suffice.
CustomAuthorizeAttribute
public class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
// Get the authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = HttpContext.Current.Request.Cookies[cookieName];
// If the cookie can be found, use the base authentication
if (authCookie != null)
{
base.OnAuthorization(filterContext);
}
else
{
// The cookie is not found, check the session for the principal
var p = HttpContext.Current.Session[FormsAuthentication.FormsCookieName];
if (p != null)
{
// there is a principal object in the session
MyCustomPrincipal principal = (MyCustomPrincipal)p;
HttpContext.Current.User = principal;
// we've loaded the principal, now just do the base authorization
base.OnAuthorization(filterContext);
}
else
{
// there is no principal object in the cookie or the session, the user is not authenticated
HandleUnauthorizedRequest(filterContext);
}
}
}
}
Once we've set the current principal appropriately using the custom authorize attribute, we can then just use the base authorization, so we don't have to worry about implementing that functionality ourselves. The base authorization should check the current principal and authorize based off of that.
I'm not going to mark this as an answer, because it doesn't really solve the underlying issue, but I thought I'd provide it as a potential workaround in case someone else stumbled along a similar issue.

Asp.Net: Retaining the old browser session after closing and reopening browser instance

Is there a way I can retain the browser session after the user has closed his browser and then reopens.
The default behavior in asp.Net is that it keeps the Asp.Net SessionId in the browser cookie which expires when we close the browser. On reopen the browser asp.net generates a new SessionId and even if the old session is not expired on the server side we can not retain it.
Can we control the expiration behavior of the session cookie in Asp.Net?
You cannot reclaim the session-id as such, but you can certainly restore some of the predictable part of the session state. If you are using forms authentication, then just read the forms-auth cookie in global.asax session start and re-populate the session objects.
You can control the expiration of forms-authentication cookie manually by creating a persistent cookie by using:
FormsAuthentication.SetAuthCookie(userName, true)
Alternatively, you can fine-tune the expiration by manually changing the cookie:
Dim authCookie As HttpCookie = FormsAuthentication.GetAuthCookie(userName)
Dim authTicket As FormsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value)
Dim newAuthTicket As New FormsAuthenticationTicket(authTicket.Version, authTicket.Name, authTicket.IssueDate, expireDate, authTicket.IsPersistent, userData)
authCookie.Value = FormsAuthentication.Encrypt(newAuthTicket)
authCookie.Expires = newAuthTicket.Expiration
HttpContext.Current.Response.Cookies.Set(authCookie)
Where expireDate specifies when the cookie should expire.
Now in global.asax session start you can check if the returning user is still authenticated (by virtue of persistent cookie previously set):
If HttpContext.Current.User.Identity.IsAuthenticated Then
' Here re-populate the predictable part of session state
' Like user profile etc.
End If
Added after Op insights:
Forms authentication is not being used, and the aim is to be able to just restore the previous session.
In such a case the only option is to persist the existing session by way of a persistent cookie, so that you can retrieve it later. There are some workarounds to achieve this. One of the workarounds is explained here by this blog writer:
http://weblogs.asp.net/imranbaloch/archive/2010/06/09/persisting-session-between-different-browser-instances.aspx
What is happening here is that we intercept two events in the global.asax:
PostRequestHandlerExecute: (Occurs when the ASP.NET event handler finishes execution) In this handler, we create a new cookie (say temp), value of which is assigned the value of current SessionId. We make it a persistent cookie by setting the expires property to the session timeout.
PostMapRequestHandler: (Occurs when ASP.NET has mapped the current request to the appropriate event handler) In this handler, we check the returning user by checking the existence of the "temp" cookie. If found, we update the actual session cookie (ASP.NET_SessionId) with the value of our "temp" cookie; thereby effectively restoring the previous session.
Please note that this is just a workaround. The system is designed to create a new session. All we are doing is to use a few hooks to workaround this by persisting an existing session to retrieve it later. All security implications stand.
At the Least you can retrieve Session information. This can be done easily when you set the 'Mode' to "SqlServer".
You can Query the Database (ASPState) & hence the table (ASPStateTempSessions) where you are storing your Sessions.[ I used persistent storage: -sstype p ]
SELECT TOP 5 [SessionId]
,[Created]
,[Expires]
,[LockDate]
,[LockDateLocal]
,[LockCookie]
,[Timeout]
,[Locked]
,[SessionItemShort]
,[SessionItemLong]
,[Flags]
FROM [ASPState].[dbo].[ASPStateTempSessions]
Even if you know your sessionID, you may use it to restore your previous session. Asp.Net will generate a new SessionID when you do a new request.

cookies and the session state object

Anyway, my main concern is using Session. I've always been under the impression that if you use the following statements (not that I would):
Session["newVar1"] = "a new session variable";
Session["newVar2"] = "a new session variable";
Session["newVar3"] = aLargeVariableThatHoldsLotsOfData;
You would be creating 3 new session cookies that hold the particular value. But I think my asp book is indicating that you would actually create 3 new variables in your session state object and ASP would only pass a unique Session ID (as a cookie?) in the response, and would get this ID upon the next request and associate that ID with your Session State Object (that IIS has stored in memory..?):
...it creates a session state object
that contains a unique session ID for
each user's session. This ID is passed
back to the browser as part of the
response and then returned to the
server with the next request. ASP.NET
can then use the session ID to get the
session state object that's associated
with the request.
That doesn't seem ideal for a website with lots of traffic. A server that is storing and maintaining thousands and thousands of instances of session state per website seems like way too much overload.
I'm trying to see what's going on on my own, but I'm having trouble.. I can't find my site's cookies anywhere on my machine (IE/windows xp). I've checked C:\Documents and Settings\nicholasr\Cookies\ and C:\Documents and Settings\nicholasr\Local Settings\Temporary Internet Files which, according to this yahoo answer, IE cookies are stored as well. I'm using ticket authentication in my app which stores a auth cookie on the client, so a cookie from my site has to be somewhere..
I guess I'm asking:
1) If someone can help me understand how Session State works behind the scenes
2) Where is IE storing my site's cookies? ><
There is a single session cookie which represents a GUID. The session values itself are stored on the server. So when you write:
Session["newVar1"] = "a new session variable";
Session["newVar2"] = "a new session variable";
Session["newVar3"] = aLargeVariableThatHoldsLotsOfData;
an HTTP cookie that might look like this is sent to the client. This cookie contains only an id, not the actual values. The actual values could be stored either in the server memory, a separate process, or even SQL Server depending on the <sessionState mode="" in web.config. Then when later the client sends another request it will send this cookie id to the server and given id the server will fetch the actual values.
The client browser stores those cookies in memory, meaning that if you close it, the session will be lost because session cookies are not persistent.

how to change session id after login in asp.net

I have a website that's using forms authentication and membership. A user must have cookies enabled to use the site. I've been asked to change the code so that the session id is changed as soon as a user logs in. Aparently this will protect against a Session Fixation attack (http://en.wikipedia.org/wiki/Session_fixation). Does anyone know how I can change the session id without losing the whole session ? PHP has a specific method for doing this but I can't find a .NET equivalent.
Here's a blog post that talks about this:
ASP.NET does not directly support
functionality to regenerate a session
ID. See the documentation regarding
the issue here. There is a not-so
quick and dirty way to do it by
setting the ASPNET_SessionID value to
the empty string and redirecting so
that the value is regenerated.
I have answered a similar question at Generating a new ASP.NET session in the current HTTPContext. Basically we must change some of the SessionStateModule internal state to be able to regenerate session ID without losing objects in the Session. I used reflection to set the _rqId field to the new ID and _rqSessionStateNotFound to true. The downside is we must grant "Full Trust" to the Application.
This is a really old question I'm resurrecting, but here's the solution:
var manager = new SessionIDManager();
bool redirected, isAdded;
manager.SaveSessionID(System.Web.HttpContext.Current,
"5vonjb4mtb1of2fxvhjvkh5d", out redirected, out isAdded);
// sessionId now equals "5vonjb4mtb1of2fxvhjvkh5d"
var sessionId = Session.SessionID;
The method suggested in Microsoft's obsolete KB article 899918 works well even for .NET framework 4.5 Web Forms applications. Here is the archive of the article: https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/899918
How and why session IDs are reused in ASP.NET
Article ID: 899918
Article Last Modified on 9/8/2006
APPLIES TO
Microsoft .NET Framework 1.1
INTRODUCTION
This article describes how and why Microsoft ASP.NET session IDs are used.
MORE INFORMATION
The ASP.NET session state is a technology that lets you store server-side, user-specific data. Web applications can use this data to process requests from the user for which the session state was instantiated. A session state user is identified by a session ID. The session ID is delivered by using one of the following methods:
The session ID is part of a cookie that is sent to the browser of the user.
The session ID is embedded in the URL. This technique is also known as a cookie-less session.
Session IDs are a 120-bit random number that is represented by a 20-character string. The string is formatted so that it can be included in a URL and it does not have to undergo URL encoding. For example, the string may be used in cookie-less sessions. The most commonly used method of delivering session IDs is by using cookies to store the session IDs.
When a user first opens their Web browser and then goes to a Web site that implements ASP.NET session state, a cookie is sent to the browser with the name "ASP.NET_SessionId" and a 20-character value.
When the user browses within the same DNS domain, the Web browser continues to send this cookie to the domain for which it was sourced.
For example, app1.tailspintoys.com and app2.tailspintoys.com are both ASP.NET applications. If the user goes to app1.tailspintoys.com and then goes to app2.tailspintoys.com, both applications would use the same cookie and the same session ID to track the session state of the user within each application. The applications do not share the same session state. The applications only share the session ID.
Therefore, you can reuse session IDs for several reasons. For example, if you reuse session IDs, you do not have to do the following:
Create a new cryptographically unique session ID when you are presented with a valid session ID.
Create a new session ID for every ASP.NET application that is in a single domain.
When the Web application requires a logon and offers a log off page or option, we recommend that you clear the session state when the user has logged off the Web site. To clear the session state, call the Session.Abandon method. The Session.Abandon method lets you flush the session state without waiting for the session state time-out. By default, this time-out is a 20-minute sliding expiration. This expiration is refreshed every time that the user makes a request to the Web site and presents the session ID cookie. The Abandon method sets a flag in the session state object that indicates that the session state should be abandoned. The flag is examined and then acted upon at the end of the page request. Therefore, the user can use session objects within the page after you call the Abandon method. As soon as the page processing is completed, the session is removed.
When you use the in-process session state mode, these session state objects are stored in the HttpCache. The HttpCache supports a callback method when the following conditions are true:
A cache entry is removed.
The Session State Manager registers the Session_OnEnd event handler to be called when the cache entry is removed.
When the Session State Manager removes a session state object that resides in the cache, the HttpCache manager will call any registered callbacks. In effect, this behavior raises the Session_OnEnd event handler.
When you abandon a session, the session ID cookie is not removed from the browser of the user. Therefore, as soon as the session has been abandoned, any new requests to the same application will use the same session ID but will have a new session state instance. At the same time, if the user opens another application within the same DNS domain, the user will not lose their session state after the Abandon method is called from one application.
Sometimes, you may not want to reuse the session ID. If you do and if you understand the ramifications of not reusing the session ID, use the following code example to abandon a session and to clear the session ID cookie:
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
This code example clears the session state from the server and sets the session state cookie to null. The null value effectively clears the cookie from the browser.
When a user does not log off from the application and the session state time-out occurs, the application may still use the same session state cookie if the browser is not closed. This behavior causes the user to be directed to the logon page and the session state cookie of the user to be presented. To guarantee that a new session ID is used when you open the logon page (login.aspx), send a null cookie back to the client. To do this, add a cookie to the response collection. Then, send the response collection back to the client. The easiest way to send a null cookie is by using the Response.Redirect method. Because the cookies collection always has a value for the ASP.NET_SessionId, you cannot just test if this cookie exists because you will create a Response.Redirect loop. You can set a query string on the redirect to the logon page.
Or, as illustrated in the following code example, you can use a different cookie to tell if you are already redirected to the logon page. To help enhance security and to make sure that no one tries to open the logon page by using a second cookie together with the ASP.NET cookie, the following code example uses the FormsAuthentication class to encrypt and decrypt the cookie data. Then, the code example sets a 5-second time-out.
private void Page_Load(object sender, System.EventArgs e)
{
if( !IsPostBack && ( Request.Cookies["__LOGINCOOKIE__"] == null || Request.Cookies["__LOGINCOOKIE__"].Value == "" ) )
{
//At this point, we do not know if the session ID that we have is a new
//session ID or if the session ID was passed by the client.
//Update the session ID.
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
//To make sure that the client clears the session ID cookie, respond to the client to tell
//it that we have responded. To do this, set another cookie.
AddRedirCookie();
Response.Redirect( Request.Path );
}
//Make sure that someone is not trying to spoof.
try
{
FormsAuthenticationTicket ticket =
FormsAuthentication.Decrypt( Request.Cookies["__LOGINCOOKIE__"].Value );
if( ticket == null || ticket.Expired == true )
throw new Exception();
RemoveRedirCookie();
}
catch
{
//If someone is trying to spoof, do it again.
AddRedirCookie();
Response.Redirect( Request.Path );
}
Response.Write("Session.SessionID="+Session.SessionID+"<br/>");
Response.Write("Cookie ASP.NET_SessionId="+Request.Cookies["ASP.NET_SessionId"].Value+"<br/>");
}
private void RemoveRedirCookie()
{
Response.Cookies.Add(new HttpCookie("__LOGINCOOKIE__", ""));
}
private void AddRedirCookie()
{
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket(1,"Test",DateTime.Now,DateTime.Now.AddSeconds(5), false,"");
string encryptedText = FormsAuthentication.Encrypt( ticket );
Response.Cookies.Add( new HttpCookie( "__LOGINCOOKIE__", encryptedText ) );
}

ASP.NET cookie expiration time is always 1/1/0001 12:00 AM

I'm setting the cookie expiration using the following code:
// remove existing cookies.
request.Cookies.Clear();
response.Cookies.Clear();
// ... serialize and encrypt my data ...
// now set the cookie.
HttpCookie cookie = new HttpCookie(AuthCookieName, encrypted);
cookie.Expires = DateTime.Now.Add(TimeSpan.FromHours(CookieTimeOutHours));
cookie.HttpOnly = true;
response.Cookies.Add(cookie);
// redirect to different page
When I read the cookie timeout in the other page I'm getting 1/1/0001 12:00 AM. If someone can help me figure out the problem, I'll appreciate it. I'm using ASP.NET 3.5
ok. after reading the links from Gulzar, it appears that I cannot check cookie.Expires on the HttpRequest at all? Because the links seem to suggest that cookie.Expires is always set to DateTime.MinValue because the server can never know the actual time on the client machine? So this means I have to store the time inside the cookie myself and check it? Is my understanding correct?
thanks
Shankar
The problem here doesn't really lie with ASP.NET but with the amount of information that is provided in the http request by browsers. The expiry date would be unobtainable regardless of the platform you are using on the server side.
As you have summarised yourself in your question the Expires property of the HttpCookie object that is provided by the HttpRequest object is always set to 1/1/0001 12:00 AM.
This is because this expiry information, as well as the properties such as domain and path, are not passed by the browser to the server when it sends a request. The only cookie information that is sent is the name and value(s). Therefore cookies in the request will have default values for these 'missing' fields as they are unknown on the server side.
I would guess the reason behind this is that the expiry, domain and path attributes of a cookie are only intended to be used by the browser when it is making a decision as to whether it should pass a cookie in a request or not and that the server is only interested in the name and value(s).
The work around you have suggested of duplicating the expiry time as another value of the cookie is a way to get the behaviour you are looking for.
At first I also disappointed why Request cookie doesn't have the actual Expires value. After debugging the http by using Fiddler2. I know that .NET was not wrong, instead, http protocol is the answer why Request cookies behaving like that.
If you use Fiddler between your app and the browser. You can see the Response cookie sent correctly to browser with all domain, path, expires, secure and httponly. However next Request cookie in http cookie header doesn't have the expires value, it only cookie name and value. Browser responsible to send this request header and I believe that is because http protocol. The reason why is because to minimize size and web server doesn't need to check it since they actually set all the values. They should notice.
So you no need to check the expires value on web request since you already know the date. Just, if you receive the cookie back that means the cookie is not yet expired. Once you set the expires, browser will handle the expiry. If you want to change the expires, just set the new value on the response.
CallMeLaNN
To solve this problem I add a claim to the principal which I can then read back and display the cookie expiry time to the user as follows:
public static void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString(string.Format("~/Login.aspx"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SetExpiryClaim
}
});
app.MapSignalR();
}
private static Task SetExpiryClaim(CookieValidateIdentityContext context)
{
var contextExpireUtc = context.Properties.ExpiresUtc;
var claimTypeName = "contextExpireUtc";
var identity = context.Identity;
Claim contextExpiryClaim;
if (identity.HasClaim(c => c.Type == claimTypeName))
{
contextExpiryClaim = identity.FindFirst(claimTypeName);
identity.RemoveClaim(contextExpiryClaim);
}
contextExpiryClaim = new Claim(claimTypeName, contextExpireUtc.ToString());
context.Identity.AddClaim(contextExpiryClaim);
return Task.FromResult(true);
}
Then you are able to retrieve the expiry time later from the ClaimsPrinciple by
ClaimsPrincipal principle = Thread.CurrentPrincipal as ClaimsPrincipal;
DateTime contextExpiry = principle.Claims.First(p => p.Type == "contextExpireUtc").Value.AsDateTime();
The version problem discussed in the link was not helpful. Basically ASP.NET cookie sucks. I had to store the expiration date time inside the cookie myself and check it in every request.
I had a similar problem when testing with an Iphone. The problem was due to the Iphone having the wrong date time set on the device, thus setting the cookie expire date to datetime.now.adddays(-1) did not expire the cookie
A request from a browser sends only the name and value of the cookies as follows:
GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
So this is not a problem in ASP.NET. And as mentioned in some answers and comments the expiration date is to determine whether to send that cookie to the server or not. So if the cookie was expired, it would be null on the server.
Also the workaround would be storing another value on that cookie that determines the expiry date (if you really need it)
Reference: Using HTTP cookies

Resources