[. Net role-based security verification] II: ASP. NET Forms authentication process analysis

Source: Internet
Author: User
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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.