Cookies not working in https server asp.net - asp.net

I am using both session and cookie to save information login details in sign in page and then checking this session and cookie before displaying details in the other page. Below is my code in sign in page
Session["PartnerId"] = authenticate.ToString();
//Cookie
HttpCookie CookiePartnerId = new HttpCookie("PartnerId");
CookiePartnerId.Value = authenticate.ToString();
//CookiePartnerId.Expires = DateTime.Now.AddHours(24);
Response.Cookies.Add(CookiePartnerId);
and here is the another page which retrieving session and cookie value
if (Session["PartnerId"] != null)
{
PartnerId = Convert.ToInt32(Session["PartnerId"].ToString());
}
else
{
PartnerId = Convert.ToInt32(Request.Cookies["PartnerId"].Value);
}
But now what I am facing is session is working fine but when it expires the cookie is not able to set the value ie (it is null). I am thinking of removing the session but cookie alone is not working.
I observed that in my local environment cookie is working but it is not working on the server. Is this because of SSL (https) I have in server? Or is there anything related to cookie I am not doing? Please advice

Related

Setting Path and SameSite Attribute to All cookies of my Application

I am working on an ASP.Net Webforms Application. My security guy wants all cookies to have Path and SameSite attribute. I can set Path and SameSite attribute to the cookies which i have created but how do set it on Session Cookie. FOr eg whenver a visitor visits my site i set some Session Variables to ASP.net generates a session cookie on Get Request, how Do i set path and SameSite attribute on First Get Request. Is there any Global.asax event which i can use. I have tried using Application_PreSendRequestHeaders event like below
protected void Application_PreSendRequestHeaders()
{
foreach (string str in Response.Cookies.AllKeys)
{
HttpCookie ck = Request.Cookies[str];
ck.Path = "/DBTDASHBOARD";
ck.Value+=";SameSite=Strict";
}
}
But this works on subsequent requests and not the first get call made to my landing page. Any help would be of great use.
Finally I was able to do this with the help of url reweite 2.0 module for IIS.

.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.

Cookie seems to never exist

I am facing a weird issue regarding cookies: I am trying to set up a cookie with the user id the first time the user logs into the application, and next time, if the cookie exists, not require the user authentication again.
For this I am using the code below:
to set the cookie:
HttpCookie userCookie = new HttpCookie("UserCookie");
userCookie.Value = UserId.ToString();
userCookie.Expires = DateTime.Now.AddHours(1);
System.Web.HttpContext.Current.Response.Cookies.Add(userCookie);
to get the cookie:
HttpCookie UserCookie = System.Web.HttpContext.Current.Request.Cookies["UserCookie"];
if (UserCookie != null)
{
// redirect the user to another screen inside the application
}
The weird thing is that my cookie seems not to exist and the user is prompted with the log in screen all the time. When I try to use debugging, it appears to me that the cookie is not null, but it's got an empty string value. What can I do about this?
Many thanks!
Are you trying to GET the cookie in the same code that SETS the cookie? If so, the cookie won't exist. Cookie gets SET on the users browser when the page has been delivered.
Also, can you confirm UserID.ToString() isn't actually an empty string..?
To test properly, set the cookie on page A, then redirect to page B and GET the cookie here.

Maintaining same session after browser closes and reopens

I am new to asp.net. I login the site and created session for userid consider this session as s1.
Add an cookie (c1) to client site with expiration of 3 days is added.
Suppose if i close the browser without logout and again i use the same url then i found session is null but i got cookie (c1) then i created a new session. But session s1 is still occupies memory on server. Means this time two sessions are on the same server occupying memory.
I want to use session s1 with the cookie (c1) - is it possible. or i want to delete session s1 if second time the request comes.
The code I used is:
if (Session["UserInfo"] != null)
{
// code
}
else
{
HttpCookie HT = Request.Cookies["User"];
if (HT != null)
{
Session["UserInfo"] = HT["UserName"]; //Here new session is created while previous is already exist on server
}
else
{
//code
}
}
IE generate a new session id on each request. So when u close your browser old Session id is get lost, so browser sends request with new session id. That's why u are not able to get value of session.
But on server it occupies server memory , which is cleared by server after session time out.
Firefox sends request with same session id on each request, u can get your session Id even if u close your browser tab.
Typical ASP configuration cookie with Forms Authentication:
.ASPXFORMSAUTH expires: 30 min
ASP.NET_SessionId expires: At end of session
So when you close your browser, you will loose session but you won't be logged off.
When you reopen browser only ASP.NET_SessionId is expired.
If you want to create persistent session cookies use this:
Create Persistent ID Cookies

Is it possible to delete subdomain cookies?

If there is a cookie set for a subdomain, metric.foo.com, is there a way for me to delete the metric.foo.com cookie on a request to www.foo.com? The browser (at least Firefox) seems to ignore a Set-Cookie with a domain of metric.foo.com.
Cookies are only readable by the domain that created them, so if the cookie was created at metric.foo.com, it will have to be deleted under the same domain as it was created. This includes sub-domains.
If you are required to delete a cookie from metric.foo.com, but are currently running a page at www.foo.com, you will not be able to.
In order to do this, you need to load the page from metric.foo.com, or create the cookie under foo.com so it can be accessable under any subdomain. OR use this:
Response.cookies("mycookie").domain = ".foo.com"
...while creating it, AND before you delete it.
..untested - should work.
I had the same problem with subdomains. For some reason getting the cookie first from the request didn't work. Instead I ended up just creating a new cookie with the same cookie name, and expiry date in the past. That worked perfectly:
void DeleteSubdomainCookie(HttpResponse response, string name)
{
HttpCookie cookie = new HttpCookie(name);
cookie.Expires = DateTime.Now.AddMonths(-1);
cookie.Domain = ".yourdomain.com";
response.Cookies.Add(cookie);
}

Resources