Check if currently logged in user has persistent authcookie - c#

I need to edit userdata in an a FormsAuthentication AuthCookie of the currently logged in user. I don't see how to find out if the current user has chosen a persistent cookie ("Remember Me").
//user is already logged in...
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(username, ispersistant); //how to I determine 'ispersistant'?
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, NEWuserdata);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
HttpContext.Current.Response.SetCookie(authCookie);
Anybody got any ideas?
Thanks

The FormsAuthentication.GetAuthCookie method only creates a new cookie. It does not get you the earlier made cookie.
On your login page you probably have something like this:
FormsAuthentication.GetAuthCookie (userID, chkPersistCookie.Checked)
And to know when the user is authenticated you can do
this.Context.User.Identity.IsAuthenticated
I actually don't know for sure if you can deduce the fact that the user has a persistent auth cookie. One thing is checking the cookie for a expiry date.
In this question there is a example for reading the authentication cookie.

This should retrieve the existing forms auth cookie, examine the ticket, and tell if it's persistent.
var FormsAuthCookie = Response.Cookies[FormsAuthentication.FormsCookieName];
var ExistingTicket = FormsAuthentication.Decrypt(FormsAuthCookie.Value);
bool IsPersistent = ExistingTicket.IsPersistent;

I ended up storing "ispersistant" in the userdata property of the authcookie on login.

Related

Store Id after authentication ASP net web forms

I would like to save the user ID after the forms authentication is made through email and password. I am currently using a session to do so;
However the session and the form authentication have different timeouts and because the session is a server type of variable when one user is logged in if I login with a different username on another machine the session simple changes its value and that is a major issue.
Besides Caching is there any other way to accomplish it?
You can store user ID in expanded authentication cookie. On authorization routine compose custom cookie and add it to response:
var ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(60), false, userId.ToString()));
HttpContext.Current.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)) { HttpOnly = true });
You can decrypt that cookie for authenticated request and find out what was user ID:
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
int iserId = int.Parse(authTicket.UserData);

AuthorizeAttribute not recognizing AuthCookie in ASP.NET

Upon successful Login I have this line
FormsAuthentication.SetAuthCookie(a.username, true);
Then I have several pages which require login to be accessed, so I added the [Authorize] attribute to them like so
[Authorize]
public ActionResult Upload()
{
return View();
}
However, after logging in, such functions still return a 401 - Unauthorized error page just as if the user had not logged in. The error page states:
Logon Method Anonymous
Logon User Anonymous
Furthermore, in my project Anonymous Authentication is enabled and Windows Authentication is disabled.
I am looking for a solution where funcitons like Upload() are always available to any logged in user.
What you can do and what I've done is to write your own cookie this way:
FormsAuthenticationTicket authTicket = new
FormsAuthenticationTicket(1, //version number of ticket
userName, // UserName
DateTime.Now, //cookie creation time
DateTime.Now.AddHours(24), //Expiration time . cookie valid for 1 day
true, //Persistent
userData); // other data to store in ticket
// set Cookie
Response.SetCookie(
new HttpCookie(
FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(authTicket)) //// encrypt ticket
{
Expires = DateTime.Now.AddHours(24),
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL
});
"Forms authentication needs to be enabled, look in your web.config if you have in system.web" – glacasa

c# Update Cookie, without forcing the user to login

I have a 'UI' setting that controls the appearance, which the user can change the setting, however it involves updating the cookie.
I seem to be able to update, but it forces the user to authenticate again, how can i update the cookie without getting the user to autenticate again?
//We need to update the userToken as the menuOptionChanged
var usertoken2 = new UserToken(schedule.MinimisedMenuBool);
HttpCookie cookie = FormsAuthentication.GetAuthCookie(usertoken.UserName, false);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
var newticket = new FormsAuthenticationTicket(ticket.Version,ticket.Name,ticket.IssueDate,ticket.Expiration,false,usertoken2.CalculateRawToken(),ticket.CookiePath);
// Encrypt the ticket and store it in the cookie
cookie.Value = FormsAuthentication.Encrypt(newticket);
System.Web.HttpContext.Current.Response.Cookies.Set(cookie);
Why are you saving UI appearance preferences in the authentication cookie?
Is there anything wrong with just saving it as a separate cookie?
HttpCookie menuCookie = new HttpCookie("menuCookie");
menuCookie.Values.Add("menuAppearance", schedule.MinimisedMenuBool);
menuCookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(menuCookie);
Then you can optionally only parse that cookie for logged in users.

Problems erasing HTTP Cookie

I have a cookie which stores user info like username, companID etc.
I need to be able to update the cookie if the user logs off and back on using a different account.
The problem I have is that I can't get rid of the previous details. I am expiring the cookie and then trying to give it a new company ID which it will then use to collect the user details but it won't overwrite it.
if (Request.Cookies["UserInfo"] != null)
{
HttpCookie myCookie = new HttpCookie("UserInfo");
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
UserInfo.Values.Add("CompanyID", Convert.ToString(ds.Tables[0].Rows[0]["ID"]));
Response.Cookies.Add(UserInfo);
Now after this the cookie still stored the old details with old company ID.

FormsAuthenticationTicket expiration

I have been searching the web and found many odd answers and i've tried almost all of them.
My problem is this. My login page contains:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(min), persistCookie, userid.ToString());
string encTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
cookie.Expires = ticket.Expiration;
Response.Cookies.Add(cookie);
FormsAuthentication.RedirectFromLoginPage(userName, persistCookie);
Now the min value is per user based and can be set individually, so is persistCookie.
After what i understand this code should result in the possibillity of overriding the default values in web.config. Which should be 30 minutes.
<authentication mode="Forms">
<forms loginUrl="~/Default/default.aspx" defaultUrl="~/User/UserMain.aspx"/>
</authentication>
min is currenlty set to 120, and persistCookie is set too true. When i log in i get timeout at 30 minutes. (Not session, so somewhere expiration date is set, because if it was not set the cookie should be session based, also i do not get 120 minutes which is kind of the deal here)
My question, for simplifying it, is how do i get the value 'min' to be the expiry date of the cookie?
This might turn out too be a simple thing but i am currently totally stuck so any help would be appriciated.
EDIT:
I changed the login logic to this:
FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(min), persistCookie, userid.ToString());
string encTicket = FormsAuthentication.Encrypt(fat);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = fat.Expiration });
Response.Redirect(FormsAuthentication.GetRedirectUrl(userName, false));
And now it works. But i cant seem to figure out why this would work, and not the previous one.
Ticket creation is the same, the only difference is that i add Expires property of the HttpCookie when creating the HttpCookie, not after the object is made.
If anybody has a good explanation i am all ears! :)
The problem with your code is that you're calling RedirectFromLoginPage, which will create the forms authentication cookie, overwriting the cookie you've just created:
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
cookie.Expires = ticket.Expiration;
Response.Cookies.Add(cookie);
FormsAuthentication.RedirectFromLoginPage(userName, persistCookie); <-- creates a new cookie
The cookie created by RedirectFromLoginPage will of course have the default timeout taken from configuration.
Your second version is the way to go.
I think you don't understand the difference between cookie expiration and ticket expiration dates - ticket can be considered as expired even if the cookie it is being stored in is still valid. The 4th param of FormsAuthenticationTicket constructor is responsible for the ticket expiration date.
So, to answer your question, you need to manually set expiration date of your cookie or make it long enough to exceed expiration date of your authentication ticket.

Categories