Determine when an ASP.NET Forms Authentication will expire - c#

Is it possible to determine the date & time when an ASP.NET session will expire when using Forms Authentication?
I would like to warn users when their sessions are about to expire. There is no session state & sliding expiration is disabled. Here are some of the system.web settings:
<authentication mode="Forms">
<forms defaultUrl="Default.aspx" loginUrl="Login.aspx" requireSSL="false" enableCrossAppRedirects="true" cookieless="AutoDetect" timeout="2" slidingExpiration="false"/>
</authentication>
<sessionState mode="Off"/>
The timeout / lifetime of a session is easy to determine, but should the user refresh the page within the session windows, adding the lifetime value to the date-time at reload will not be accurate.
Using an authentication cookie with FormsAuthenticationTicket ticket encrypted as its value, one can decrypt it to get the expiration date-time.
Although some AJAX calls may be made, the user might interact with the UI without any post back or request to the webserver.
Any ideas on how I can achieve this type of behavior without the use of cookies?

I have a similar problem. In my case given the low number of users, im opting for a better user experience with a polling ajax call on the page to call back into the server and check the expiration ticket. You may be able to get away with tweaking the below code and including expiration info in the page via http and keeping track of time in client javascript if you dont want to go the ajax route.
if (User.Identity.IsAuthenticated)
{
var identity = (FormsIdentity)User.Identity;
viewModel.UtcInactivityExpiryDate = identity.Ticket.Expiration.ToUniversalTime();
}
If you go the ajax route, there is another gotcha. You have to stop the ajax call itself from renewing the inactivity timeout if you are using one. You can do that by overwriting the new authentication cookie with the original one. at the end of your ajax request.
var requestCookie = HttpContext.Current.Request.Cookies[".ASPXAUTH"];
if (requestCookie != null)
{
HttpContext.Current.Response.Cookies.Add(requestCookie);
}

Related

MVC5 After Signout, Session and Cookies are cleared but still i can access mvc controller using old cookies by Postman [duplicate]

I have been banging my head against the wall and searching the web for this but I think I am having issues understanding the whole process of logging users out of an asp.net webforms application. The issue:
I am able to log in to my application and it uses cookies, so I have my cookie set in the browser.
here is the config forms authentication section,
<forms loginUrl="login.aspx" timeout="15" protection="All" name="Domain.MYDOMAIN" path="/" domain="mysite.local" cookieless="UseDeviceProfile"/>
here is the front end control
<li><asp:LoginStatus ID="LoginStatus1" runat="server" OnLoggedOut="OnLoggedOut" /></li>
In the OnLoggedOut Method we do something like this.
protected void OnLoggedOut(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
/* Abandon session object to destroy all session variables */
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
Response.Redirect("~/login.aspx");
}
This will clear the cookies from the browser. But if before I do this I copy the cookie name pair value of Domain.MYDOMAIN = "what ever it would be"
and add that to a postman call, it is still showing me as logged in! Very frustrating.
when I am logged in
I log out using the logout button mentioned above and the cookie is removed
Then I take that cookie to Postman and make the call to the landing / default page and it is showing me as logged in still!!!
I have been reading that the cookie is related to a "ticket" but I am not sure how to expire that ticket on the server side. Once the user clicks logout I dont want this cookie value to be used again to reach a page, any page within the application. Any help would be appreciated! Thank You!
Side Note: I have my session state set to InProc
<sessionState mode="InProc" />
Ones the user is authenticate with user name and password, then we set a cookie that have a time out and this cookie let him login.
Even if you delete the cookie from one browser, if you still have it and place it again – you permit to login again because the cookie is gives the “OK” to do that.
This is not only on asp.net but everywhere (Microsoft, google, Facebook).
To add an extra layer of security, and avoid to someone steal the cookie:
First step is to force only the SSL for the cookies (*). <httpCookies httpOnlyCookies="true" requireSSL="true" />. Using that you make it difficult to impossible to steal the cookie
Second step is on logout to save that cookie on a database, then on every request check if the cookies have been logged out
Third step is to also check if the cookie come from the same browser id.
So, you connect the cookie with the browser data, and with a flag that the user press the logout.
You make that checks on global.asax
protected void Application_BeginRequest(Object sender, EventArgs e)
(*) The first step : Can some hacker steal a web browser cookie from a user and login with that name on a web site?
The difficult way is to add the database extra layer of protection and connect the cookie with other user information's as I say, the browser id, and a flag if have been logged out. The main idea is to keep on server the authenticated cookie that you have set and double check it - now you don't do that.

asp.net session and forms authentication time performance hit on server?

So I was given the task to set the session time out to 24hr, doing some reading on the web i found out that i also need to set the forms authentication to that time frame so the user is not logged out. My question is , are there any drawbacks on the server side? Will it work harder/slower thanks to the fact that it has to keep all those sessions in check ?
Will it work harder/slower thanks to the fact that it has to keep all
those sessions in check ?
There is no performance improvement or slow down for Server except that user doesn't need to re-login and server doesn't need to authenticate the user again.
Once user is logged-in, server checks authentication cookie whether is still valid on every post back (doesn't matter how long or how short you set the timeout).
Normally, you want to set form authentication time out to be larger than session time out.
For example,
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880"/>
</authentication>
<sessionState timeout="1440"/>
Its actually a bit more complex than that. I can't remember which is which but they have different expiries. Session timeout resets with every request whereas the forms auth ticket only resets after at least half the time out has expired. So this needs to be double the size of the session timeout.

Cookie doesn't persist

I've got an issue with my cookies. I'm authenticating users through LDAP and as long as the browser remains open users don't have to log back into the tool. They can even close the tab that's fine so long as the browser is open.
But the cookie gets removed the moment the user closes the browser. I've searched google a lot for this and I can't get any of the solutions to work such as this one or that one for example.
Here's my setup once they authenticate on my logon page:
String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
//Create a cookie, and then add the encrypted ticket to the cookie as data.
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
//Add expiration date to the cookie
authCookie.Expires = DateTime.Now.AddMonths(1);
//Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);
//You can redirect now.
FormsAuthentication.RedirectFromLoginPage(txtUsername.Text, false);
My Web.Config looks like this:
<authentication mode="Forms">
<forms loginUrl="Logon.aspx" timeout="43200" name="adAuthCookie" path="/" slidingExpiration="true" />
</authentication>
Whatever I do the ASP.NET_SessionId and adAuthCookie cookies are always set to expire "When I close my browser".
I want to avoid my users to always have to login when they close their browser and instead just do it once a month.
Sounds like you need to set a machineKey in your web.config.
If one is not specified either there or machine.config, it will be generated on start up and reset everytime the website is restarted, invalidating the encryption in the cookie.
machineKey element
Make sure browser is not set to delete cookies on close. There is such paranoid setting somewher in security options (I think in IE it is Advanced -> Security ->Empty temporary folders...)
Use Fiddler or other tool to make sure you send cookies with correct expiration to the browser. This way you verify where error is server or client side.

Windows Identity Foundation Security Token Service can't stay logged in

I'm using the Windows Identity Foundation (WIF) Security Token Service (STS) to handle authentication for my application which is working all well and good. However I can't seem to get any long running login with the STS.
From my understanding I shouldn't care about the client tokens at the application level since they can expire all they want to and it should redirect me to the STS and as long as they're still logged in on the STS it should refresh their application token. Yet it doesn't seem to want to keep them signed in.
Here's what occurs in my login.aspx on the STS
var cookie = FormsAuthentication.GetAuthCookie(userName, persistTicket);
if (persistTicket)
cookie.Expires = DateTime.Now.AddDays(14);
Response.Cookies.Add(cookie);
var returnUrl = Request.QueryString["ReturnUrl"];
Response.Redirect(returnUrl ?? "default.aspx");
Which was taken almost directly from existing application using normal Forms Auth.
From my web.config
<authentication mode="Forms">
<forms loginUrl="Login.aspx" protection="All" timeout="2880"
name=".STS" path="/" requireSSL="false" slidingExpiration="true"
defaultUrl="default.aspx" cookieless="UseDeviceProfile"
enableCrossAppRedirects="false" />
</authentication>
Looking at the cookie after I sign in I can see the expires time on the cookie is set for 14 days in the future and that the cookie is NOT a session cookie.
When I'm required to log back into the STS I can see that my original cookie is still there.
Is there some kind of time stamp functionality that the STS embeds into the cookie that is invalidating my cookie even though as far as I know it should still be valid?
After reading the suggestion from #uosel this lead me down the path of doing more indepth analysis on what exactly is occurring here. Whereas my goal is to create a persistent cookie only for the STS itself and not for the STS consuming sites. This way I can always validate the user at the STS level at any expiration of a STS consuming site.
With more locomotion in this train of thought it dawned on me that the STS starter site uses forms auth to secure the actual WIF authorization that occurs in the index.aspx. That the issue was I had no logic that would use an existing forms auth ticket to process the transfer to the forms auth secured index page.
This lead me to a solution similar to
if(User.Identity.IsAuthenticated)
{
if(IsValidUserCredentials())
{
var returnUrl = Request.QueryString["ReturnUrl"];
Response.Redirect(returnUrl ?? "default.aspx");
}
}
else
{
DisplayLoginForm()
}
If you are using passive redirects, do you have persistentCookiesOnPassiveRedirects set to true?
<wsFederation passiveRedirectEnabled="true"
persistentCookiesOnPassiveRedirects="true" />

FormsAuthentication class c#

If I call FormsAuthentication.SetAuthCookie("john", true), is the users name stored in the cookie?
What I'm trying to find out is if the users session times out and then the user revisit the site again, Request.IsAuthenticated is set to true, but where is the users name coming from?
Session timeout and authentication timeout are two separate things. You can have sessions time out without invalidating the authentication.
Yes, the user's name is stored in the authentication cookie. It is encrypted, however.
You can use your browser to examine the content of your cookies. For example my stack over flow cookie looks like:
F650CE82F53D2C39C8C06B5F26EB34E20FEAC3585035E2A6E9FA30B8ECF5051F4D9C8....
The value is an encrypted goo of a username and potentially the user roles.
The cookie is good as long as you want it to be. It isn't tied to the session.
In your sample code you created a persistent cookie, so it lives for the life of the cookie, even if you close your browser. Now if the cookie is memory based, it lasts until you close your browser, even if the expiration time would let it live longer.
Here are the default values:
<forms loginUrl="Login.aspx"
protection="All"
timeout="30"
name=".ASPXAUTH"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="default.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false" />
As from this MSDN page it sets forms-authentication ticket to either cookies or in URL if CookiesSupported is set false.
When you set second argument as true, the cookie is persistent so when user visits second time (after session timesout) your app gets the cookie with auth-ticket and so it get the user details (as far as I think).
If you don't want to make this happen I think either setting the second argument to false:
FormsAuthentication.SetAuthCookie("john", false);
or explicitly clearing the ticket (and so cookie):
FormsAuthentication.SignOut();
will work for you.

Categories

Resources