Classic FormsAuthenticationTicket Analysis

Source: Internet
Author: User
Tags http cookie httpcontext

Role authentication authorization based on Forms authentication in ASP.

There are three types of authentication for ASP. Windows | Forms | Passport ", which is the most and most flexible for forms verification.
The Forms authentication method provides good support for user-based authentication authorization, which can authenticate the user through a login page, send the user's identity back to the client's cookie, and then the user accesses the Web app and sends it to the server along with this identity cookie. The authorization settings on the server can control the access authorization of different users according to different directories.

The problem is that, in practice, what we often need is role-based, or user-group-based authentication and authorization. For a Web site, the general mode of authentication authorization should be: according to the actual needs of the user into different identities, that is, the role, or the user group, verification process not only to verify the identity of the user itself, but also to verify that it belongs to which role. Access authorization is set based on roles, what resources some roles can access, what resources are not accessible, and so on. If the user-based access will be a very impractical approach, the user has a lot of, but also may be at any time to increase or decrease, it is not possible in the configuration file for the increasing number of new users to add access to authorization.

Here's a look at the process of forms.

Basic principles of Forms authentication:

One authentication

To use Forms authentication, you first need to make the appropriate settings in Web. config in the application root directory:

<authentication mode= "Forms" >
<forms name= ". Aspxauth "loginurl="/login.aspx "timeout=" "path="/">
</forms>
</authentication>

where <authentication mode= "Forms" > indicates that the application uses forms authentication.
1. The name in the <forms> tab indicates the HTTP Cookie that is specified to be used for authentication. By default, the value of name is. Aspxauth. After authenticating the user in this way, a FormsAuthenticationTicket type of authentication ticket is established with this user's information, and then the encryption is serialized to a string, Finally, this string is written to the client's name in the specified name of the cookie. Once this cookie is written to the client, the user will be sent to the server with a cookie once it is posted to the Web app, and the server will know that the user has been authenticated.

And look at what information the authentication ticket contains, let's look at the FormsAuthenticationTicket class:
cookiepath: Returns the path where the Cookie was issued. Note that the path of the form is set to/. Because the form is case-sensitive, this is a safeguard that is taken to prevent inconsistencies in the case of URLs in the site. This is used when refreshing cookies
Expiration: Gets the date/time when the Cookie expires.
ispersistenT: Returns True if a persistent Cookie has been issued. Otherwise, the authentication Cookie will be limited to the browser lifecycle.
issuedate: Gets the date/time when the Cookie was originally issued.
name: Gets the user name associated with the authentication Cookie.
UserData : Gets the application definition string stored in the Cookie.
version: Returns the byte revision number for future use.


2. The loginurl in the <forms> tab specifies the URL to which the login will redirect the request if no valid authentication Cookie is found. The default value is default.aspx. Loginurl The specified page is used to verify the user's identity, generally this page provides user input user name and password, the user submitted by the program to verify the legality of the user according to their own needs (most of the situation is the user input information in the database with the user table to compare), if the authentication user is valid, Generates an authentication ticket corresponding to this user, writes to the client's cookie, and finally redirects the browser to the page requested by the user. Generally, the FormsAuthentication.RedirectFromLoginPage method is used to complete the generation of the authentication ticket, Write back a series of actions such as client, browser redirection and so on.

public static void RedirectFromLoginPage (string userName, bool createPersistentCookie, string strcookiepath);

which
UserName: This is the user's mark, used to mark the user's unique identifier, not necessarily mapped to the user account name.
createPersistentCookie: Indicates whether a persistent Cookie is issued.
If it is not persistent cookie, The validity period of a cookie expiration property has the current time plus the timeout in Web. config, each time the page is requested, during the authentication process, it will determine if half of the validity period is expired, and if so, the expiration date of the cookie is updated; if persistent cookie,expiratio The n attribute is meaningless, when the validity of the authentication ticket is determined by the expires of the cookie, and the RedirectFromLoginPage method sets the 50-year validity period for the Expires attribute.
strCookiePath: Indicates the path of the cookie that will be generated to the client, the path that is saved in the authentication ticket is used when the authentication ticket cookie is refreshed (this is also the path to generate the cookie), and if no strCookiePath parameter is used, the The setting of the Path property.

As you can see, this method has only three parameters, and there are seven attributes for the authentication ticket, and the insufficient four parameters are:
IssueDate: The time at which the cookie is issued is derived from the current time
Expiration: The expiration time is calculated by the current time and the timeout parameter in the <forms> tag below. This parameter is meaningful for non-persistent cookies.
UserData:This property can be used by the application to write some user-defined data, this method does not use this property, but simply set this property to an empty string, please note this property, we will use this property later.
Version:The version number is automatically provided by the system.

After the RedirectFromLoginPage method generates an authentication ticket, the Formsauthentication.encrypt method is called, and the authentication ticket is encrypted to a string, which will be the string. Aspxauth is the value of a cookie for the name. The other properties of this cookie are generated: The Domain,path attribute is the exact province value, expires depending on the createPersistentCookie parameter, if the persistent cookie,expires is set to expire after 50, and if the non-persistent cookie, The Expires property is not set.
After the authentication cookie is generated, this cookie is added to the Response.Cookies and waits to be sent to the client.
Finally, the RedirectFromLoginPage method calls the Formsauthentication.getredirecturl method to obtain the page that the user originally requested, redirecting to this page.

3. The timeout and path in the <forms> tab are provided with the authentication ticket written to the cookie expiration time and the default path.

This is the process based on forms authentication, which completes the acknowledgement of the user's identity. The following describes access authorization for forms-based authentication.

Two-access authorization

Verify the identity, is to use this identity, according to different identities we can do different operations, processing, the most common is different identities for different authorization, forms authentication provides such a function. Forms authorization is directory-based and can be used to set access permissions on a directory, for example, those users can access the directory, and those users cannot access the directory.
Similarly, the authorization settings are set in the Web. config file under the directory you want to control:
<authorization>
<allow users= "comma-separated List of users"
roles= "comma-separated List of roles"
verbs= "comma-separated list of verbs"/>
<deny users= "comma-separated List of users"
roles= "comma-separated List of roles"
verbs= "comma-separated list of verbs"/>
</authorization>

The <allow> tag represents the allowed access, where the properties
1. Users: A comma-delimited list of user names that have been granted access to resources. The question mark (?) allows anonymous users, and an asterisk (*) allows all users.
2. Roles: A comma-delimited list of roles that have been granted access to resources.
3. Verbs: A comma-delimited list of HTTP transport methods that have been granted access to resources. The predicates registered to ASP. NET are, POST, and DEBUG.

The <deny> tag indicates that access is not allowed. The properties are the same as above.

At run time, the authorization module iterates through the <allow> and <deny> tags until it finds the first access rule that is appropriate for a particular user. It then allows or denies access to the URL resource based on whether the first access rule found is <allow> or <deny> rule. The default authentication rule in the Machine.config file is <allow users= "*"/>, so access is allowed by default unless otherwise configured.

So how do these user and roles get it? Here's a look at the details of the authorization process:

1. Once a user accesses the site, the login confirms the identity, and the cookie for the authentication ticket is also written to the client. After that, the user applies for the Web page again, and the cookie for the authentication ticket is sent to the server. On the service side, ASP. NET for each HTTP request is assigned a HttpApplication object to handle this request, after the Httpapplication.authenticaterequest event, the security module has established a user identity, that is, the user's identity on the web side has been established, this The identity is created solely by the cookie that the client sends back the authentication ticket.
2. User identity in the HttpContext.User attribute, the page can be page.context to get the HttpContext object associated with the page. For forms validation, the HttpContext.User property is an object of type GenericPrincipal, GenericPrincipal has only one public property identity, has a private m_role attribute, is string[] Type, which holds the array of roles that this user belongs to, and a public method IsInRole (string role) to determine whether the user belongs to a role.
Because the role is not provided in the cookie for the authentication ticket, it means that the forms authentication ticket does not provide the role information for this user, so for forms authentication, the GenericPrincipal user object that is obtained on the server is m_ The role attribute is always empty.
3. GenericPrincipal. The Identity property is an object of type formsidentity, which has a name attribute, which is the identifier of this user, and access authorization is to authenticate this attribute as user for authorization. FormsIdentity also has a property, which is the ticket property, which is the authentication ticket FormsAuthenticationTicket type, which is the authentication ticket previously written to the client by the server.
After the server obtains the authentication ticket FormsAuthenticationTicket object, it is not durable to see whether this authentication ticket is non-persistent authentication, Yes, you can update the cookie for this authentication ticket based on the validity period of the timeout attribute set in Web. config (to avoid compromising performance, update the cookie after more than half of the specified time. This can result in a loss of accuracy. Persistent cookies do not time out. )
4. Before the Httpapplication.resolverequestcache event, ASP. NET begins to obtain the user requested page and establishes the HttpHandler control point. This means that the Httpapplication.resolverequestcache event will be authenticated to the user's access rights, to see if the user or role has access to the page, and then to change the identity or role of the user within the lifetime of the request is meaningless.

The above is the whole process of forms verification, it can be seen that the forms validation is user-based, and does not provide direct support for role validation. The name attribute in the authentication ticket FormsAuthenticationTicket is a user ID, but there is also an attribute UserData, which can be used by the application to write custom data, and we can use this field to hold the information of role. So as to achieve the purpose of role-based verification.

Forms authentication role-based authorization

One authentication

The <authentication> settings in Web. config are the same:

<authentication mode= "Forms" >
<forms name= ". Aspxauth "loginurl="/login.aspx "timeout=" "path="/">
</forms>
</authentication>

/login.aspx verify the legality of the user page, after verifying the legality of the user, but also to obtain this user belongs to the role of the process, this see each application itself how to design, generally in the database will have a use_role table, It is possible to get the role of this user from the database, not to delve into how to get the role of the user, and finally be able to get all the role of this user corresponding to a comma-delimited string.
In the non-role-based approach above, we used the FormsAuthentication.RedirectFromLoginPage method to generate authentication tickets, write back to the client, browser redirection and a series of actions. This method accomplishes a series of actions with a set of exact provinces, which we cannot do with this method in role-based validation, in order to add some custom settings:

1. First create an authentication ticket based on the user ID and the string of the role that the user belongs to
Public FormsAuthenticationTicket (
int version,//set to 1
String name,//user identifier
DateTime issuedate,//cookie time, set to DateTime.Now
DateTime expiration,//expiry time
BOOL Ispersistent,//whether persistent (as required, if set to persistent, in the issue
Cookie, the expires setting of the cookie must be set)
String UserData,//This is a comma-separated role string prepared here
String Cookiepath//is set to "/", which is consistent with the path of the cookie being issued because the cookie is refreshed
To use this path
);

FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1, "Kent", DateTime.Now, DateTime.Now.AddMinutes (30) , False,userroles, "/");

2. Generate the cookie for the authentication ticket
2.1 Encrypt the authentication ticket into a string
String hashticket = Formsauthentication.encrypt (Ticket);
2.2 Generating cookies
HttpCookie Usercookie = new HttpCookie (Formsauthentication.formscookiename, Hashticket);
The formsauthentication.formscookiename is used to obtain the name of the authentication cookie set in Web. config, and the default is ". Aspxauth ".
If the Ispersistent attribute in the authentication ticket is set to a persistent class, the Expires property of the cookie must be set so that the cookie is persisted as a persistent cookie in the client's cookie file.
3. Export the authentication ticket cookie to the client
The authentication ticket cookie is appended to the output cookie collection via RESPONSE.COOKIES.ADD (Usercookie) and sent to the client.
4. Redirect to the preliminary interview page of the user request.

Verify that part of the code (this part of the code is clicked on the Login button event handling code on the Login.aspx page):

private void Buttonlogin_click (object sender, System.EventArgs e)
{
string user = Textboxuser.text; Read user name
string password = Textboxpassword.text; Read password
if (Confirm (user,password) = = True)//confirm method is used to verify the legality of the user
{
String userroles = usertorole (user); Call the Usertorole method to get the role string
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,user,datetime.now, DateTime.Now.AddMinutes (3 0), False,userroles, "/");//Establish an authentication ticket object
String hashticket = Formsauthentication.encrypt (Ticket); Encrypt serialized validation ticket as String
HttpCookie Usercookie = new HttpCookie (Formsauthentication.formscookiename, Hashticket);
Generate cookies
CONTEXT.RESPONSE.COOKIES.ADD (Usercookie); Output cookie
Context.Response.Redirect (context.request["RETURNURL"]); Redirect to initial page of user request
}
Else
{
Code when the user's identity is not acknowledged
}
}
This method is used to verify the legality of the user
private bool Confirm (string user,string password)
{
The corresponding code
}
This method is used to get all the role of the user corresponding to a comma-separated string
private string Usertorole (string user)
{
The corresponding code
}

Two role-based access authorization

What we want to do here is to restore the information stored in the UserData in the client's saved authentication ticket to the GenericPrincipal object that represents the user's identity on the server (remember that during the original validation process, The GenericPrincipal object contains only user information and does not contain role information)
In the process of an HTTP request, the Httpapplication.authenticaterequest event indicates that the security module has established a user ID, that is, the user's identity has been established on the web side, and after this event we can obtain the user identity information.
Before the Httpapplication.resolverequestcache event, ASP. NET started to obtain the user Request page, establishes the HttpHandler control point, then has to verify the user's permission, So the work of recovering a user role can only be done during the Httpapplication.authenticaterequest event and the Httpapplication.resolverequestcache event.
We choose to do this in the Application_authorizerequest event, which can handle all HttpApplication events in the Global.asax file, with the following code:

protected void Application_authorizerequest (object sender, System.EventArgs e)
{
     HttpApplication App = (HttpApplication) sender;
      HttpContext Ctx = App.context;  //Get the HttpContext object associated with this HTTP request
      if (Ctx.Request.IsAuthenticated = = true)  //authenticated user does role handling
     {
         formsidentity Id = (formsidentity) Ctx.User.Identity;
         FormsAuthenticationTicket Ticket = id.ticket;  //Get the authentication ticket
         string[] Roles = Ticket.UserData.Split (', ');  // Convert role data in the authentication ticket to a string array
         ctx.user = new GenericPrincipal (Id, Roles  //the original identity plus role information creates a new GenericPrincipal representing the current user, so that the current user has role information
    }
}

When a visitor has both user and role information, it is possible to use role in Web. config to control the user's access rights.

http://blog.163.com/[email protected]/blog/static/224186242010070024282/

FormsAuthenticationTicket decomposition

FormsAuthenticationTicket based on FormS validation

The process of building a forms-based validation mechanism is as follows:
1, set IIS to be anonymous access and set as form validation in ASP.
2. Retrieve the data store to authenticate the user and retrieve the role (if not role-based)
3, use FormsAuthenticationTicket to create a cookie and send it back to the client, and store
Role into the ticket, such as:
Formsauthentication.setauthcookie (Username,true | false)
Cookie storage Time:
Httpcontext.current.response.cookies[formsauthentication.formscookiename]. Expires=datetime.now.adddays (1)

If you need to store roles, use:
FormsAuthenticationTicket AuthTicket = new
FormsAuthenticationTicket (
1,//version number.
txtUsername.Text,//user name associated with the authentication ticket.
DateTime.Now,//The time when the Cookie was issued.
DateTime.Now.AddMinutes,//The expiration date of the Cookie.
False,//If the Cookie is persistent, true; otherwise false.
roles); User-defined data that will be stored in the Cookie.
Roles is a role string array
String encryptedticket = Formsauthentication.encrypt (AuthTicket); Encryption

Deposit Cookies
HttpCookie Authcookie =
New HttpCookie (Formsauthentication.formscookiename,
Encryptedticket);

RESPONSE.COOKIES.ADD (Authcookie);

4, in the Application_AuthenticateRequest event in the handler (Global.asax), use the
Ticket creation IPrincipal objects coexist in HttpContext.User
Code:
HttpCookie Authcookie = Context.request.cookies[formsauthentication.formscookiename];
FormsAuthenticationTicket AuthTicket = Formsauthentication.decrypt (authcookie.value);//decryption
string[] roles = authTicket.UserData.Split (new char[]{'; '}); /decomposition according to the format of the deposit;
Context.User = new GenericPrincipal (Context.User.Identity, Roles);//Save to HttpContext.User

Determine a role validation
HttpContext.Current.User.IsInRole (roles)
Specific implementation

Web. config file
Join the node, name is the cookie name, loginurl is the address that does not pass the authentication jump
<system.web>
<authentication mode= "Forms" >
<forms name= "Hstear"
Loginurl= "Login.aspx" protection= "All" path= "/" timeout= "+"/>
</authentication>
</system.web>
Set Directory access path to directory name, roles as the role name in the ticket
Found on the internet said to be a separate Web. config file in the directory, but actually set in the root directory, a single file is the same
<location path= "Admin" >
<system.web>
<authorization>
<allow roles= "admin"/>
<deny users= "*"/>
</authorization>
</system.web>
</location>
Global.asax file
The Application_AuthenticateRequest event was added

protected void Application_AuthenticateRequest (Object sender, EventArgs e)
... {
string cookiename = Formsauthentication.formscookiename;
HttpCookie Authcookie = Context.request.cookies[cookiename];
FormsAuthenticationTicket AuthTicket = null;
Try
... {
AuthTicket = Formsauthentication.decrypt (Authcookie.value);
}
catch (Exception ex)
... {
Return
}

string[] roles = AuthTicket.UserData.Split (new char[] ... {‘,‘});/ /If multiple roles are accessed, we break it down

FormsIdentity id = new FormsIdentity (AuthTicket);

GenericPrincipal principal = new GenericPrincipal (ID, roles);
Context.User =principal;//in HttpContext.User

}

http://blog.163.com/[email protected]/blog/static/2241862420100711546123/

Using Forms authentication to implement user registration, login (i) Basics

Http://www.cnblogs.com/AndersLiu/archive/2008/01/01/forms-authentication-part-1.html

Source: http://blog.csdn.net/byondocean/article/details/7164117
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1, "username", DateTime.Now, DateTime.Now.AddDays ( 365), True, string.            Format ("{0}:{1}", "username", "password"), Formsauthentication.formscookiepath); Here's the string.            Format ("{0}:{1}", "username", "password") can also be changed to any value, such as a password or ipstring ticstring = Formsauthentication.encrypt (ticket);            Save the encrypted ticket as a cookie HttpCookie COO = new HttpCookie (Formsauthentication.formscookiename, ticstring); The ispersistent here will not judge by hand, but the value of FormsAuthenticationTicket expiration is outdated, regardless of how long the expires of the cookie is set, As long as the expiration expires, even if the cookie exists, user authentication will fail if (ticket. ispersistent) {coo. Expires = ticket.            expiration;            }//Using a new Cookie Response.Cookies.Add (COO) added to UserData; Formsauthentication.setauthcookie ("username", true);//This is a quick way of writing, using this kind of writing can not be built ticket bills, also cannot use UserData parameters such as//form sauthentication.signout//is used to clear this cookie tag//formsauthentication.rediRectfromloginpage (UserID, createPersistentCookie); <authentication mode= "Forms" >//<forms name= ".  MyCookie "loginurl=" Login.aspx "protection=" All "timeout="/>//</authentication>

Summarize:

1.FormsAuthentication altogether there are two ways to generate and record a ticket:

One is your own new FormsAuthenticationTicket, and then you save it to the cookie, ticket's Ispersistent attribute only plays the role of identity, and does not modify the expiry time of the cookie, The expiry time of the cookie (if (ticket) needs to be set manually. ispersistent) {coo. Expires = ticket. expiration; })。

The other is to use Formsauthentication.setauthcookie ("username", ispersistent:false) to quickly generate ticket, This method automatically creates a new cookie to hold the ticket and determines the expiry time of the cookie based on whether Ispersistent is true and timeout in Webconfig.

2. If you use the first method, regardless of how long you set the cookie, as long as the ticket. Expiration expires, timely cookies exist, user authentication will still fail.

3.UserData is a good thing that can be used to store IP addresses to determine whether a visitor is a malicious interception of cookies.


Source: http://www.cnblogs.com/yeagen/p/3427465.html

Classic FormsAuthenticationTicket Analysis

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.