As mentioned in msdn, formsauthenticationmodule plays a key role in Forms authentication. What exactly does this hide? This section briefly analyzes the forms authentication process so that you can better understand and use it.
Formsauthenticationmodule is an HTTP module. Forms authentication participates in the lifecycle of ASP. NET pages through formsauthenticationmodule. It is initialized when the website application is started and the access request is intercepted. Let's continue to see its details.
Public void Init (httpapplication APP)
{
// Bind two events of httpapplication to intercept system access requests.
App. authenticaterequest + = new eventhandler (this. onenter );
App. endrequest + = new eventhandler (this. onleave );
}
Private void onenter (Object source, eventargs)
{
If (! Formsauthenticationmodule. _ fauthchecked | formsauthenticationmodule. _ fauthrequired)
{
Httpapplication application1 = (httpapplication) source;
Httpcontext context1 = application1.context;
// Read the configuration information for Forms authentication
Authenticationsection Section1 = runtimeconfig. getappconfig (). authentication;
Section1.validateauthenticationmode ();
// Confirm the forms Authentication Mode
If (! Formsauthenticationmodule. _ fauthchecked)
{
Formsauthenticationmodule. _ fauthrequired = section1.mode = authenticationmode. forms;
Formsauthenticationmodule. _ fauthchecked = true;
}
If (formsauthenticationmodule. _ fauthrequired)
{
// Set the default parameters
If (! This. _ fformsinit)
{
Formsauthentication. initialize ();
This. _ formsname = section1.forms. Name;
If (this. _ formsname = NULL)
{
This. _ formsname = ". aspxauth ";
}
Formsauthenticationmodule. Trace ("forms name is:" + this. _ formsname );
This. _ loginurl = section1.forms. loginurl;
If (this. _ loginurl = NULL)
{
This. _ loginurl = "login. aspx ";
}
This. _ fformsinit = true;
}
// Call the verification Core Method
This. onauthenticate (New formsauthenticationeventargs (context1 ));
Cookielesshelperclass class1 = context1.cookielesshelper;
If (authenticationconfig. accessingloginpage (context1, this. _ loginurl ))
{
Context1. _ skipauthorization = true;
Class1.redirectwithdetectionifrequired (null, formsauthentication. cookiemode );
}
If (! Context1.skipauthorization)
{
Context1. _ skipauthorization = assemblyresourceloader. isvalidwebresourcerequest (context1 );
}
}
}
}
Private void onauthenticate (formsauthenticationeventargs E)
{
Httpcookie cookie1 = NULL;
If (this. _ eventhandler! = NULL)
{
This. _ eventhandler (this, e );
}
// Check the user object to confirm whether the verification has passed.
If (E. Context. User! = NULL) | (E. User! = NULL ))
{
// Process the parameters of the global. asax formsauthentication_onauthenticate event.
If (E. Context. User = NULL)
{
E. Context. _ User = E. user;
}
}
Else
{
Formsauthenticationticket ticket1 = NULL;
Bool flag1 = false;
Try
{
// Extract the verification ticket object from the cookie
Ticket1 = formsauthenticationmodule. extractticketfromcookie (E. context, this. _ formsname, out flag1 );
}
Catch
{
Ticket1 = NULL;
}
If (ticket1! = NULL )&&! Ticket1.expired)
{
Formsauthenticationticket ticket2 = ticket1;
// Refresh ticket information
If (formsauthentication. slidingexpiration)
{
Ticket2 = formsauthentication. renewticketifold (ticket1 );
}
// Create the subject and ID object
E. Context. _ User = new genericprincipal (New formsidentity (ticket2), new string [0]);
If (! Flag1 &&! Ticket2.cookiepath. Equals ("/"))
{
Cookie1 = E. Context. Request. Cookies [This. _ formsname];
If (cookie1! = NULL)
{
Cookie1.path = ticket2.cookiepath;
}
}
If (ticket2! = Ticket1)
{
If (flag1 & (ticket2.cookiepath! = "/") & (Ticket2.cookiepath. length> 1 ))
{
Ticket2 = new formsauthenticationticket (ticket2.version, ticket2.name, ticket2.issuedate, ticket2.expiration, ticket2.ispersistent, ticket2.userdata ,"/");
}
// Encrypt the new ticket and write the cookie.
String text1 = formsauthentication. Encrypt (ticket2 );
If (flag1)
{
E. Context. cookielesshelper. setcookievalue ('F', text1 );
E. Context. response. Redirect (E. Context. Request. pathwithquerystring );
}
Else
{
If (cookie1! = NULL)
{
Cookie1 = E. Context. Request. Cookies [This. _ formsname];
}
If (cookie1 = NULL)
{
Cookie1 = new httpcookie (this. _ formsname, text1 );
Cookie1.path = ticket2.cookiepath;
}
If (ticket2.ispersistent)
{
Cookie1.expires = ticket2.expiration;
}
Cookie1.value = text1;
Cookie1.secure = formsauthentication. requiressl;
Cookie1.httponly = true;
If (formsauthentication. cookiedomain! = NULL)
{
Cookie1.domain = formsauthentication. cookiedomain;
}
E. Context. response. Cookies. Add (cookie1 );
}
}
}
}
}
Private void onleave (Object source, eventargs)
{
// Adjust the URL
If (formsauthenticationmodule. _ fauthchecked & formsauthenticationmodule. _ fauthrequired)
{
Httpapplication application1 = (httpapplication) source;
Httpcontext context1 = application1.context;
If (context1.response. statuscode = 0x191)
{
String text3;
String text1 = NULL;
If (! String. isnullorempty (this. _ loginurl ))
{
Text1 = authenticationconfig. getcompleteloginurl (context1, this. _ loginurl );
}
If (text1 = NULL) | (text1.length <= 0 ))
{
Throw new httpexception (Sr. getstring ("auth_invalid_login_url "));
}
Cookielesshelperclass class1 = context1.cookielesshelper;
String text2 = context1.request. pathwithquerystring;
If (text1.indexof ('? ')> = 0)
{
Text1 = formsauthentication. removequerystringvariablefromurl (text1, "returnurl ");
Text3 = text1 + "& returnurl =" + httputility. urlencode (text2, context1.request. contentencoding );
}
Else
{
Text3 = text1 + "? Returnurl = "+ httputility. urlencode (text2, context1.request. contentencoding );
}
Int num1 = text2.indexof ('? ');
If (num1> = 0) & (num1 <(text2.length-1 )))
{
Text2 = formsauthentication. removequerystringvariablefromurl (text2, "returnurl ");
}
Num1 = text2.indexof ('? ');
If (num1> = 0) & (num1 <(text2.length-1 )))
{
Text3 = text3 + "&" + text2.substring (num1 + 1 );
}
Class1.setcookievalue ('F', null );
Class1.redirectwithdetectionifrequired (text3, formsauthentication. cookiemode );
Context1.response. Redirect (text3, false );
}
}
}
By analyzing the formsauthenticationmodule code, we can basically determine the ASP. NET Forms authentication process.
1. Intercept System Access and check the authentication status.
2. Skip to the specified loginurl for user identity data verification if the verification fails.
3. If the verification has passed, the authentication ticket object will be extracted from the cookie.
4. Create a user ID and a subject object. The object contains a ticket reference.
5. Update the ticket expiration time and write the cookie again.
6. Adjust the URL parameters to redirect the page.
Throughout the verification process, we can see several verification core types. Including:
Formsauthenticationticket: an identity verification ticket that stores user names, expiration times, custom data, and other information. Encrypted as a string by formsauthentication. encrypt, and then saved to the cookie or URL parameter.
Genericprincipal: user subject object. Httpcontext. user is the type used to save user identity data, such as formsidentity and formsauthenticationticket.
Formsidentity: User Identification object, which can be accessed through httpcontext. Current. User. Identity. Its ticket attribute stores the user authentication ticket reference.
Httpcontext: the context object created by ASP. NET for each user. It is used to save relevant information of the user, such as session and genericprincipal.
Formsauthentication: one of the core classes for ASP. NET Forms authentication. Its static attributes can be used to access the Forms Web. config configuration. Relevant methods are used to operate on authentication data.