Form authentication slidingExpiration does not work - c#

I have below code
int intTimeout = (FormsAuthentication.Timeout.Hours * 60) +
FormsAuthentication.Timeout.Minutes;
var authTicket = new FormsAuthenticationTicket(1, Utility.userCookie, DateTime.Now,
DateTime.Now.AddMinutes(intTimeout), true, cookieValue);
string strEncryptedTicket = HttpUtility.UrlEncode(FormsAuthentication.Encrypt(authTicket));
var authCookie = new HttpCookie(Utility.userCookie, strEncryptedTicket);
authCookie.Expires = authTicket.Expiration;
//FormsAuthentication.RedirectFromLoginPage("", false);
authCookie.Secure = FormsAuthentication.RequireSSL;
//authCookie.Secure = true;
HttpContext.Current.Response.Cookies[Utility.userCookie].Expires = authTicket.Expiration;
HttpContext.Current.Response.Cookies[Utility.userCookie].Value = authCookie.Value;
Below web.config
<authentication mode="Forms">
<forms timeout="2" slidingExpiration="true" requireSSL="true" />
</authentication>
I keep hitting page link, still it expires in 2 minutes.

Please pay attention to the structure of custom forms–based authentication in web.config:
<forms
name="name"
loginUrl="URL"
defaultUrl="URL"
protection="[All|None|Encryption|Validation]"
timeout="[MM]"
path="path"
requireSSL="[true|false]"
slidingExpiration="[true|false]">
enableCrossAppRedirects="[true|false]"
cookieless="[UseUri|UseCookies|AutoDetect|UseDeviceProfile]"
domain="domain name"
ticketCompatibilityMode="[Framework20|Framework40]">
<credentials>...</credentials>
</forms>
As you see, timeout property works based on minutes where you set it 2 (e.g. 2 minutes).
Generally, if you enable slidingExpiration in web.config. You have no need to regenerate a new cookie manually. For your scenario, I suggest you to use a trace tool e.g. Fiddler. When you refresh the page, you can check from Fiddler that whether the cookie expired time is reset.
I found a good example in Weird Timeouts With Custom ASPNETFormsAuthentication which can do some clearance for you.

Maybe the problem is related to lack of static machineKey section in the web.config file. when you call FormsAuthentication.Encrypt or FormsAuthentication.Decrypt, the methods use the machineKey values which is provided in the web.config file to perform the operation. if you do not provide strict values for machineKey, a new unique validationKey and decryptionKey would generate at the start point of the web application. sometimes depend on the server settings(for example small Idle-Time values for application pool settings), application is terminated before the expiration time of the FormsAuthenticationTicket. in this case because of the new machineKey values the Decrypt method can't validate the Ticket. I just recommend you to set a static machineKey.
see the following link:
https://msdn.microsoft.com/en-us/library/w8h3skw9(v=vs.100).aspx

Try to remove this line from your code and try again:
HttpContext.Current.Response.Cookies[Utility.userCookie].Expires = authTicket.Expiration;

In web.config file either remove <clear/> element or add following after <clear/> element if not present.
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>

In my application, I define cookieAuthenticationOptions in Startup.cs like this and it works fine
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
ExpireTimeSpan = TimeSpan.FromHours(1),
SlidingExpiration = true,
CookieHttpOnly = true,
CookieName = "App.Authentication",
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
});
Do you define those options ?
Why you don't use the SignIn method of AuthenticationManager ?

Related

HttpContext.Current.User.Identity.Name is always null

I know this question has been asked before but each question has a different scenario to what I have or I am missing the obvious.
So I have implemented SSO architecture, so the user click on log in and redirected to identity server and log in there and get redirected back to the application.
in one of my application I want to use the HttpContext.Current.User.Identity.Name in my membershipprovider, but it is always empty. so I found out that I need create a cookie and set it up properly to get the HttpContext.Current.User.Identity.Name form wherever I want.
My code look like this:
After the user is redirected from the Identity server to a login control:
if (!System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
HttpContext.Current.Session["username"].ToString(),
DateTime.Now, DateTime.Now.AddMinutes(30), true, String.Empty,
FormsAuthentication.FormsCookiePath);
string encryptedCookie = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedCookie);
cookie.Expires = DateTime.Now.AddMinutes(30);
Response.Cookies.Add(cookie);
FormsAuthentication.RedirectFromLoginPage("/my-profile", true);
}
My web config file looks like this:
<authentication mode="Forms">
<forms domain="http://localhost:8081" name="yourAuthCookie" loginUrl="login.aspx"
protection="All" path="/" />
</authentication>
<authorization>
<allow users="?" />
</authorization>
after the user is redirected to the my profile page the System.Web.HttpContext.Current.User.Identity.IsAuthenticated is true and the AuthinticationType = Cookies. but the Name is empty.
I am using asp.net webforms.
UPDATE: I have tried to set the HttpContext.Current.User it is set properly but when the page load or redirected it goes back to null empty.
if (ticket != null && !ticket.Expired)
{
var roles = ticket.UserData.Split(',');
System.Web.HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(ticket), roles);
}
any help will be much appreciated.
Your domain is wrong - in your app.config; <forms domain="http://localhost:8081" ... /> in this context domain has a meaning of domain into which the cookie is set. You can read more about domain of cookies here.
Domain is something like www.google.com or .google.com etc - it doesn't contain protocol prefix, it doesn't contain port and it makes no sense to use it for local hosts - so drop that attribute from your web.config for good.
Also (and this has nothing to do with your issue, it's just a friendly suggestion) - you don't have to construct forms auth ticket when all you care about is username. You can use just FormsAuthentication.SetAuthCookie instead.

Access Cookie into sub domains

I want to host multiple sites under one domain. But currently I am working on localhost, so I added these 2 lines to my etc/hosts file:
127.0.0.1 something.com
127.0.0.1 orders.something.com
There are 2 applications hosted in IIS. One can be browsed using: orders.something.com/OrdersSSO and other can be browsed using something.com/SSOSample/.
I created authentication cookie using this code in something.com/SSOSample/:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
"abc",
DateTime.Now,
DateTime.Now.AddMinutes(30), // value of time out property
true, // Value of IsPersistent property
String.Empty,
FormsAuthentication.FormsCookiePath);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie authCookie = new HttpCookie(
FormsAuthentication.FormsCookieName,
encryptedTicket);
Response.Cookies.Add(authCookie);
So I am logged in this application. However when I browse orders.something.com/OrdersSSO I don't get my authentication cookie.
This is my forms section in web.config:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" enableCrossAppRedirects="true" timeout="2880" domain=".something.com" />
</authentication>
What am I missing?
Looks like your cookie doamin has not been correctly set.
Try something like this :
authCookie.Domain = ".something.com"
Note the "." in front of the domain name, that's what makes it work for any subdomain of something.com.

Why isn't .ASPAUX cookie being validated by FormsAuthentication?

I have a site that uses FormsAuthentication and yes, the name of the cookie is .ASPAUX :)
I can log in perfectly. The server creates a forms authentication ticket, packs it in a cookie, properly determines the expiration time (1 year ahead) and sends it to the client.
For some reason, after some time, even though the cookie is there yet (I can see it with FireCookies) HttpContext.Current.Request.IsAuthenticated becomes false at the server. It's as if the cookie couldn't be validated.
The problem is: Why would that happen? How can I debug why the cookie suddenly becomes invalid without expiring?
EDIT
Here's the login method:
public static bool Login(int id)
{
try
{
string securityToken = UserHelper.AuthenticateUser(id);
DateTime expiryDate = DateTime.Now.AddYears(1);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, id.ToString(), DateTime.Now, expiryDate, true,
securityToken, FormsAuthentication.FormsCookiePath);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.Expires = expiryDate;
HttpContext.Current.Response.Cookies.Add(cookie);
return true;
}
catch
{
return false;
}
}
And the web.config:
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" timeout="2880" slidingExpiration="true"/>
</authentication>
Set static machine keys in your web.config to make sure that the encryption key used in generating your ticket survives an application pool being recycled (or your website being restarted in the ASP.NET web server)?
Also see the Forms Authentication Tickets section of this MSDN library article
A few things I can think of to check:
Do you have multiple domains (including www.domain.com vs domain.com)?
If so, either set the domain in the cookie as domain.com or ensure you always use the same domain
Are you using HTTPS?
If so, make sure you're always accessing the cookie via HTTPS or making sure that Secure is set to false on the HttpCookie (otherwise it's only accessible on HTTPS requests)
Are you writing the cookie from a virtual directory?
If so, the "path" on the cookie might be set and it won't be accessible from outside the path.
Do you have multiple web servers?
If so, make sure your machine key is set to the same value (though that should be throwing an exception)

authCookie not secure in global.asax

I have a login problem.
First i am using SSL while logging.
When i log in, i am creating a cookie like this. when i check if it is secure the answer is yes.
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, // version
UserName.Text, // user name
DateTime.Now, // creation
DateTime.Now.AddMinutes(60),// Expiration
false, // Persistent
role); // User data
// Now encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// Create a cookie and add the encrypted ticket to the
// cookie as data.
HttpCookie authCookie =
new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket);
if (authCookie.Secure)
{
new GUIUtility().LogMessageToFile("The cookie is secure with SSL.");
// Add other required code here.
}
authCookie.Secure = FormsAuthentication.RequireSSL;
// Add the cookie to the outgoing cookies collection.
HttpContext.Current.Response.Cookies.Add(authCookie);
// Redirect the user to the originally requested page
Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,false));
then this is redirected to the global.asax page which has this code:
string cookieName = FormsAuthentication.FormsCookieName.ToString();
HttpCookie authCookie = Context.Request.Cookies[cookieName];
try
{
new GUIUtility().LogMessageToFile(cookieName + authCookie.Secure);
}
catch (Exception)
{
//
}
here i get the cookieName as ".ASPXAUTH" and authCookie.Secure value as False.
Why is this happening i want the authCookie.Secure value to be true here.
Any suggestions?? thanks
my web config has this:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" defaultUrl="~/Default.aspx" slidingExpiration="true" timeout="120" path="/" requireSSL="true" protection="All">
</forms>
</authentication>
<httpCookies requireSSL="true"/>
<authorization>
<deny users="?"/>
<!--<allow users="*"/>-->
</authorization>
Restrict the Authentication Cookie-to-HTTPS Connections
Cookies support a "secure" property that determines whether or not browsers should send the cookie back to the server. With the secure property set, the cookie is sent by the browser only to a secure page that is requested using an HTTPS URL.
If you are using .NET Framework version 1.1, set the secure property by using requireSSL="true" on the element as follows:
<forms loginUrl="Secure\Login.aspx"
requireSSL="true" . . . />
If you are using .NET Framework version 1.0, set the secure property manually in the Application_EndRequest event handler in Global.asax using the following code:
protected void Application_EndRequest(Object sender, EventArgs e)
{
string authCookie = FormsAuthentication.FormsCookieName;
foreach (string sCookie in Response.Cookies)
{
if (sCookie.Equals(authCookie))
{
// Set the cookie to be secure. Browsers will send the cookie
// only to pages requested with https
Response.Cookies[sCookie].Secure = true;
}
}
}
so according to me the first option is not working in web config so im doing it manually
which is the second option in the code..
Please suggest.
Are you redirecting on log-in to a non-SSL resource? If this is the case, then the cookie you created in the first piece of code shouldn't be used, because it's a secure cookie and hence only applicable to SSL connections (i.e. you explicitly said it shouldn't be sent to non-SSL requests, that's what .Secure does), and hence a new cookie would be created. I would expect it to also not include the ticket value.
In this case, you're going to want to either:
Keep with SSL from the point of being logged in.
Live with the risk of session stealing (there are further means of mitigating this risk).
Use an authentication protocol like Digest or NTLM that allows for challenge-response and for you to more rapidly expire the log-in without the user being pestered (because the browser does the second log-in for you).

C# Formsauthentication timeout in web.config overrules manual ticket timeout?

I have a testproject and the forms timeout specified in web.config overrules the timeout which I set in FormsAuthenticationTicket. According the documentation, the timeout (expire date) in FormsAuthenticationTicket must override the timeout in web.config.
Documentation found on: http://support.microsoft.com/kb/910443
If the ticket is generated manually by using the FormsAuthenticationTicket class, the time-out can be set through the Expiration attribute. This value will override the timeout attribute value specified in configuration files.
Here is my code:
Web.config:
<authentication mode="Forms">
<forms
timeout="1"
loginUrl="login.aspx"
name="sessionTest"
cookieless="UseCookies"
defaultUrl="default.aspx"
/>
</authentication>
Login.aspc.cs:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(Login1.UserName, false, 2);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(cookie);
// redirect user
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, false);
Now, when I login, i get redirected after 1 minute of inactivity. This isn't supposed to happen, right? I have to be redirected after 2 minutes.
Someone can explain this?
I think the call to RedirectFromLoginPage is overwriting your cookie. You can try using this instead.
Response.Redirect( FormsAuthentication.GetRedirectUrl( UserName.Text, chkPersistCookie.Checked );
Additional information that might be useful here: https://web.archive.org/web/20210513002246/https://www.4guysfromrolla.com/webtech/110701-1.3.shtml

Categories

Resources