-
Notifications
You must be signed in to change notification settings - Fork 0
Forms Authentication
Forms authentication is a feature added in ASP.NET 1.1, and get enhanced with the introducing of membership and security controls in ASP.NET 2.0. Before that many classical ASP and ASP.NET applications store user information like user identity such as username as session variables. Since http communication is stateless, classical ASP applications and ASP.NET applications always maintain a session for each browser. A session always exists no matter the user logs in or not. Such session is often called browser session since there exists one session per browser at any time. A session consists of a session Id and session state. A session Id is generated from server side and is stored in cookie and sends with each request to server, in this way at the server side we can recognize requests from the same browser. Session state is an array of data associated with a session id and lives at server side only. At server side, we can find the user data in session state by the session Id sent from client side. Session states can be stored on different places on server, such as in database, or in a separate state service, but most often in memory. If we store user data in memory session, then restarting application pool would kick users out of the application.
Forms authentication stores username, and other user data if necessary, as an encrypted cookie, thus can survive from application pool restart. When we store user identity in session state, for each request, we need to check session state to decide if user is authenticated. ASP.NET framework provides extra support to the forms authentication which makes it easy to use, for example since the server has knowledge of user is authenticated, we can use settings in web.config, outside of application code, to prevent unauthorized users from access the site or certain pages. We can use User.IsAuthenticated to check if user is authenticated, and from User.Identity we can find username as well as the ticket content.
Forms authentication does not restrict the way to authenticate users. Often once we get the username and password user provided, we verify them against user information stored in database, then call the FormsAuthentication.SetAuthCookie with the username to generate the forms authentication ticket cookie, then the user is authenticated.
Session timeout value can be set in web.config and the default value is 20 minutes. Session timeout can be either fixed, which means no matter what you do, after that many minutes the session ends; or sliding, which means bore session expires when you send request to server the session expiration time is extended to expire that many minutes from the current time therefore session ends only when we have not sent any request to server for that many minutes. Forms authentication ticket also has a timeout value can also be set in web.config and the default is 30 minutes, and the expiration can also be fixed or sliding. The meaning of sliding is a little different, the expiration time gets extended only if a request is sent to server when the ticket is going to expire within half of the timeout value.
Session and ticket can timeout separately and independently. If we want the session always timeout before ticket expires, then we just need to make the ticket timeout to be at least double of the session timeout value. Say session time is N minutes and ticket timeout is 2N minutes. In order for the ticket timeouts, there cannot be any request to server in the last N minutes before the expiration. But if there is no request in N minutes, the session would timeout, thus it timeout before the ticket expires. One advantage of doing that is we can have an opportunity to expire the ticket when session timeout, thus make them expire at the same time. See https://itworksonmymachine.wordpress.com/2008/07/17/forms-authentication-timeout-vs-session-timeout/.
In general a http module needs to be registered in web.config for it to be used in the web application, but then how come I do not find FormsAuthenticationModule mentioned in my web.config? It is registered in a root web.config (C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config/web.config) that every web applications uses, for more details, see https://stackoverflow.com/questions/20163911/where-is-formsauthenticationmodule-registered.
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>We know the forms authentication ticket gets extended only when user sends a request to server after half way through the expiration time. Exactly where does this logic implemented? It is implemented in the RenewTicketIfOld method of the FormsAuthentication class, which is called by the FormsAuthenticationModule class in the handler (OnEnter->OnAuthentication) to the AuthenticateRequest event.
public static FormsAuthenticationTicket RenewTicketIfOld(FormsAuthenticationTicket tOld) {
if (tOld == null) return null;
DateTime utcNow = DateTime.UtcNow;
TimeSpan ticketAge = utcNow - tOld.IssueDateUtc;
TimeSpan ticketRemainingLifetime = tOld.ExpirationUtc - utcNow;
if (ticketRemainingLifetime > ticketAge) return tOld; // no need to renew
// The original ticket may have had a custom-specified lifetime separate from
// the default timeout specified in config. We should honor that original
// lifetime when renewing the ticket.
TimeSpan originalTicketTotalLifetime = tOld.ExpirationUtc - tOld.IssueDateUtc;
DateTime newExpirationUtc = utcNow + originalTicketTotalLifetime;
FormsAuthenticationTicket ticket = FormsAuthenticationTicket.FromUtc(
tOld.Version /* version */,
tOld.Name /* name */,
utcNow /* issueDateUtc */,
newExpirationUtc /* expirationUtc */,
tOld.IsPersistent /* isPersistent */,
tOld.UserData /* userData */,
tOld.CookiePath /* cookiePath */);
return ticket;
}Say we have multiple applications share the same form authentication ticket, the new expiration time when a ticket get renewed is based on the timeout setting of the application that initially create the ticket, or the timeout setting of the application that renews this ticket? Based on the code of the RenewTicketIfOld method, it is based on the timeout setting of the application that initially create the ticket.