asp.net implementation of form certification some of the use of skills (must read) _ Practical skills

Source: Internet
Author: User
Tags constructor decrypt parent directory prepare reflector ticket account security connectionstrings

Most recently, because project code refactoring requires a reorganization of user logins and permission controls, the existing code is generally referenced. NET form certification, and combined with the Portal Kits login control, the code is verbose, the maintainability is relatively poor. The following requirements are available (most systems should be encountered):

1. NET with the form certification to achieve secure login

2. Log in after the user needs to record the basic information to facilitate all page calls

3. Log machine login status, short time to close the window without having to log in again

4. Permission control and Code folder structure echoes, that is, by role to allow access to different directories

5. Permission control may need to be refined to each page, that is, by role to allow access to different pages

6. The above part as far as possible to write less code, with its own class library and mechanism to achieve

The first step: Prepare for work

First prepare a Web project named Test that contains:

Default.aspx, default page, display some information casually,

Login.aspx, login page, put two text boxes above, used to enter username and password, a login button, a hyperlink to the Register.aspx,

register.aspx, User registration page, registered user information, casually put a little text box, mainly to simulate the registration, do not really realize,

Web.config, configure the page.

The registration page and the login page are in the same directory after the machine is wonderful.

Step two: Modify the Web.config file

1, Open the Web.config file, find the authentication section, change it as follows:

<authentication mode= "Forms" >
  <forms name= ". Aspxauth "loginurl=" Login.aspx "protection=" All "path="/"timeout="/>
</authentication>
< authorization>
  <deny users= "?" ></deny>
</authorization>

The specific meaning of the configuration section properties and other attributes that are not joined are found everywhere. Note here that the authentication and authorization, two words are similar, but not the same word, each section below the content can not be written together.

where "allow" in the authorization section denotes the meaning of the permission, "*" means all users, and "Deny" means "deny"; Represents an anonymous user; When added here, all files that represent the root directory and all subdirectories cannot be accessed anonymously, except for login.aspx pages.

2, The application of Location section in Web.config

After the above configuration, we will find that, in the case of not logged in, the browser to open the Default.aspx will automatically go to Login.aspx, the same register.aspx page. Question: How can a registered user be able to access it after logging in?

Then we have to say that when the registration page is in the same directory as the login page, in order to achieve the purpose of accessing the registration page without logging on, we have to deal with the Web.config configuration of the access restrictions.

Method One: The registration page and the login page are not in the directory

We add a folder pub to the root directory, move register.aspx to this folder, still can't access, need to add a Web.config file in the folder, join:

<configuration> 
 <system.web> 
  <authorization>
   <allow users= "*"/>
  </ Authorization> 
 </system.web> 

Here, all the files in this directory are described, allowing access to all people.

A description of the scope of Web.config action:

The web.config settings will be used for all the files in the directory and all the things under their subdirectories (Inheritance: Child with parent last name)

• The Web.config setting in the subdirectory overrides the settings inherited by the parent directory (overwrite: The magistrate is inferior to the current management)

• That is, the attribute setting is determined by the web.config in the deepest level of the directory; if there is no Web.config file in the subdirectory, it is determined by the web.config from the nearest parent directory

Method Two: Still keep the registration page and the login page in the same directory

Just add the following paragraph to the web.config in the root directory:

<location path= "register.aspx" >
 <system.web>
   <authorization>
    <allow users= "*" >
   </authorization>
 </system.web>
</location>

The register.aspx page is specified by the value of the Path property of the Location section, and the settings for the authorization section below explain the register.aspx the page is allowed to be accessed by everyone.

Attention:

The location section should be added to the outer part of the original system.web section, contained within the configuration section, and the system.web section is of the same sibling.

When there are multiple pages in the root directory that you can access without having to log on, you can set up multiple location sections and modify the page that points to the path attribute value.

Alternatively, thevalue of the path attribute can specify a directory that specifies the access restrictions for that directory. restrict access by modifying the contents of the authorization section. Detailed settings, which will be mentioned later.

Step three: Implement the code for the login

1, the Common Code implementation

Method One:

If you set the properties of "Defaulturl" in the Forms section, which is the page that is turned on by default after you log on, you can use the following method:

private void Btn_login_click (object sender, System.EventArgs e) 
{ 
 if (this. txt_username.text== "Admin" && this. txt_password.text== "123456") 
 { 
   FormsAuthentication.RedirectFromLoginPage (this. Txt_username.text,false); 
 } 

Here is a simple simulation of the login verification process, RedirectFromLoginPage method can send verification ticket verification cookie (how to do can use reflector to view the source code), return to the request page, that is, "from where to play." For example: The user does not log in directly in the IE address bar input http://localhost/Test/Default.aspx, then the user will see is login.aspx? Returnurl=default.aspx, enter the username and password after the successful login, the system will be based on the "ReturnUrl" value, return the corresponding page, if there is no "ReturnUrl", the "Defaulturl" automatically turn to the properties.

Method Two:

private void Btn_login_click (object sender, System.EventArgs e)
{ 
  if (this. txt_username.text== "Admin" && this. txt_password.text== "123456") 
  { 
   Formsauthentication.setauthcookie (this. Txt_username.text,false); 
   Response.Redirect ("default.aspx"); 
  } 
 


Here is two steps: After the verification of the direct release of cookies, jump page will be the programmer to specify their own, do not need "defaulturl" settings. This approach is more flexible for programmers.

2, manual implementation needs to record the user login information

When we need to record the user login information, not just an ID also need more attributes, usually with a class stored to the session or cookie implementation, and then do a base class page, in the base class page set properties to read session or cookie.

The session actually has to do with unsupported cookies, and there are servers and how much of it consumes server-side resources. So consider using cookies here. If the RedirectFromLoginPage method or the SetAuthCookie method has set up the verification ticket and set the cookie, can we also store the user login information in this default cookie? The answer is yes.

First, we add the Appcode directory to the project, adding a userinfo class to simply simulate user login information. The code is as follows:

[Serializable]
public class UserInfo
{
  //user login information
  private int _nid;
  private string _srealname;
  private string _sname;  
  private string _spassword;
  private string _sroles;

  public int Id
  {get
    {This._nid;}
    set {This._nid = value;}
  }
  public string realname
  {get
    {return this._srealname;}
    set {this._srealname = value;}
  }
  public string Name
  {get
    {this._sname;}
    set {this._sname = value;}
  }
  public string Password
  {get
    {return this._spassword;}
    set {This._spassword = value;}
  }
  public string Roles
  {get
    {return this._sroles;}
    set {this._sroles = value;}
  }

  Public UserInfo ()
  {    
  }
}

It is important to note that the properties of the class must be added [Serializable] to indicate that the class can be serialized.

The internal mechanism of forms validation is to encrypt user data and save it in a cookie-based bill FormsAuthenticationTicket, either by RedirectFromLoginPage method or The SetAuthCookie method has already implemented the ticket and cookie settings, which means that the Context.User value is set, and context.user is useful in determining whether the value is validated or not. The properties of the cookie are in the Web.config <forms Name= ". Aspxauth " loginurl=" Login.aspx " protection=" All " path="/" timeout=" > set in the. Because it is specially encrypted, it should be more secure.

and. NET in addition to using this ticket to store their own information, but also left a place to give users the freedom of control, which is now to say the ticket of the UserData. UserData is used to store string types of information, and also enjoys the encryption protection provided by forms validation, which, when needed, can also be obtained through simple ticket UserData properties, taking into account security and ease of use. It is useful to save some of the necessary sensitive information. We are ready to record the user's login information in UserData, the code is as follows:

 protected void Button1_Click (object sender, EventArgs e) {if (this. TextBox1.Text = = "Admin" && this.
      TextBox2.Text = = "123456") {//encrypt UserInfo UserInfo user = new UserInfo (); User.
      Id = 1; User. Name = this.
      TextBox1.Text; User. Password = this.
      TextBox2.Text; User.
      Realname = "system Administrator"; User.
      Roles = "Administrators,users";

      String struser = serialize.encrypt<userinfo> (user); Set Ticket information FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1, user.

      Name, DateTime.Now, DateTime.Now.AddMinutes (), false, struser);

      Cryptographic verification Ticket String strticket = Formsauthentication.encrypt (ticket);
      Use the new UserData to save the cookie HttpCookie cookie = new HttpCookie (Formsauthentication.formscookiename, Strticket); Cookie. Expires = ticket.
      expiration; This.
      

      RESPONSE.COOKIES.ADD (cookie); This.
    Response.Redirect ("default.aspx"); }
}

The code above, in fact, is similar to the process of manually implementing the SetAuthCookie method.

First of all, simulate implementation login, we manually set up a UserInfo object,string struser = serialize.encrypt< UserInfo>(User) is a method of serializing an object into a string.

Then, a FormsAuthenticationTicket ticket is generated. The signature interpretation of the overloaded method of the FormsAuthenticationTicket constructor used here

Public FormsAuthenticationTicket ( 
int version,//version number
string name,////user name DateTime associated with the authentication ticket
issue Date,//Bill's issue time
DateTime expiration,//Bill expiration date
bool Ispersistent,//whether the bill is stored in a persistent Cookie, is true; otherwise false
the user-defined data stored in the string UserData//ticket
);

Where the setting of name corresponds to Context.User.Identity.Name and is case sensitive and is also related to future permissions control, special attention is required when assigning values. In addition, the expiration date of the bill and the expiration date of the cookie set in Web.config are not the same concept, if not clear, please go to the Internet to search, if you really do not want to work on this, there will be a way to deal with.

Again, string strticket = Formsauthentication.encrypt (ticket) encrypts the ticket into a character creation

Finally, the HttpCookie cookie = new HttpCookie (formsauthentication.formscookiename, strticket) generates cookies.

Formsauthentication.formscookiename Gets the cookie name that is configured in the Web.config and the cookie that is generated by default validation. Cookie. Expires = ticket. Expiration the expiration of the ticket and the expiration time of the cookie, and avoids the contradiction between the differences. Thus, the validation ticket is generated and stored in a cookie in the default configuration, which is similar to the process of implementing a SetAuthCookie method. The information about the bill can be obtained by Context.User.

3, access to information

In order to get the login user information more simply after the other login page, our husband is a base class page. New Loginbasepage class in Appcode, code as follows:

public class Loginbasepage:page
{
  protected UserInfo loginuser
  {
    get
    {
      string struser = ( FormsIdentity) this. Context.User.Identity). Ticket.userdata;

      Return serialize.decrypt<userinfo> (struser);        
    }

  Public Loginbasepage ()
  {
    ///
    TODO: Add constructor logic here/
    /
  }
}

Loginbasepage:page, the Base class page inherits page and becomes the base class for all pages that have been logged on.

Property protected UserInfo loginuser{get;} to access logon information. Converts the Context.User.Identity to the object of the FormsIdentity class, obtains the string of the serialized object by accessing the UserData property of the Ticket property, and ends with the method serialize.decrypt< Userinfo> (struser) deserializes the string into an object and then returns an object of the UserInfo type.

We just need to change the background code for the Default page to public partial class _default:loginbasepage, and we can pass this. Loginuser to access the user login information.

Fourth step: To achieve the rights control of different directories

Above, the implementation of the log user login information simulation of the process, and the root directory access control files. But the system usually has multiple directories, and then the access control of the directory is said.

In fact, the above has been mentioned more or less, by adding Web.config files in each directory to restrict access.

First, we add a folder manageadmin in the root directory, add page userinfo.aspx in this folder, and put several labels inside the page to show the login user information.

Then, add a Web.config file with the following configuration:

<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    < authorization>
      <allow users= "Admin" ></allow>
      <deny users= "*" ></deny>
    < /authorization>
  </system.web>
</configuration>

The configuration indicates that only "Admin" users are allowed to access, and all other users are prevented from accessing it.

In particular, it is important to note that the assignment of the name attribute of the FormsAuthenticationTicket ticket must correspond to the user of the <allow users= "Admin" ></allow> settings and is case-sensitive. If you want to set up to allow multiple users to access, separate them by "," such as <allow users= "Admin,user1" ></allow>.

Different directories, set up different users to allow access, you can access control of all directories.

Fifth step: To achieve different directory of the role of the right to control

The above implementation of the different directories by user access restrictions. But in general, a Web site system users will be many, if the use of accurate to the user's access control, it will cause the workload of setting Web.config increased.

In general, we will assign users to different user groups for rights control, so we can also configure the Web.config implementation to control the access rights of different directories by role.

First, we add a directory manageusers in the root directory, which also adds page userinfo.aspx to display the login user information. This directory simulates the user who controls the Users group, and the folder Manageadmin simulates the user who controls the Administrators group.

Then, add the Web.config file to the directory manageusers, and configure the contents as follows:

<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    < authorization>
      <allow roles= "Users" ></allow>
      <deny users= "*" ></deny>
    < /authorization>
  </system.web>
</configuration>

Then the folder Manageadmin under the Web.config file <Allow users= "Admin">< /allow> change to <allow roles= "Administrators" ></allow>.

Finally, modify the code.

1, note that we simulate the user information, there is such a sentence, user. Roles = "administrators,users"; that is, user admin has two roles

2, for the simulation Users group login, we add the following code:

if (this. TextBox1.Text = = "User1" && this. TextBox2.Text = = "111111")
{
      //encryption UserInfo
      UserInfo user = new UserInfo ();
      User. Id = 2;
      User. Name = this. TextBox1.Text;
      User. Password = this. TextBox2.Text;
      User. Realname = "Ordinary user 1";
      User. Roles = "Users";
      String struser = serialize.encrypt<userinfo> (user);

      Set Ticket information
      FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (
        1, user. Name, DateTime.Now, DateTime.Now.AddMinutes (), false, struser);

      Cryptographic verification Ticket
      string strticket = Formsauthentication.encrypt (ticket);

      Use the new UserData
      to save the cookie HttpCookie cookie = new HttpCookie (Formsauthentication.formscookiename, strticket);
      Cookie. Expires = ticket. expiration;
      This. RESPONSE.COOKIES.ADD (cookie);
      

      This. Response.Redirect ("default.aspx");
 }

In this way, when we log in, enter "Admin" and "User1", you can simulate different roles of the user login.

3. The internal mechanism of forms role-based validation is that the attributes of the role are also set to the Context.User, which also requires manual code processing.

First, in order to support role-based validation, we need to set the role information into Context.User for every page we enter, so the best approach is to set it in the Application_AuthenticateRequest method in the Global.asax file.

The Application_AuthenticateRequest method, which is triggered every time the request is validated, differs from another method application_beginrequest the Application_ Within the AuthenticateRequest method, Context.User.Identity can be accessed, while Application_BeginRequest is inaccessible.

We add a Global.asax file to the root directory, adding the following code:

protected void Application_AuthenticateRequest (Object sender, EventArgs e)
  {
    if (this. Context.User!= null)
    {
      if (this. Context.User.Identity.IsAuthenticated)
      {
        if (this. Context.User.Identity is formsidentity
        } {
          String struser = ((formsidentity) this. Context.User.Identity). Ticket.userdata;

          string[] roles = serialize.decrypt<userinfo> (struser). Roles.split (', ');

          This. Context.User = new GenericPrincipal (this. Context.User.Identity, roles);
        }}}
  

Here The main code is to cast the Context.User.Identity to the object of the FormsIdentity class by accessing the UserData property of the ticket property to obtain the string of the serialized object, and finally using the method Serialize.decrypt <UserInfo> struser the string into an object, and then separates the roles property of the UserInfo object into a role array with "," as the delimiter. Then using Context.User.Identity and role arrays to generate a new GenericPrincipal object, assigned to Context.User, context.user the validation object for which the role has been set.

According to our settings, admin users can access two directories, and User1 users, you can only access Manageusers directory.

Step Sixth: Centrally manage Web.config files

Access control of the directory, whether by user or by role, is generally determined by specific business.

However, as the directory increases, there is a Web.config file in each directory, which is especially inconvenient to manage.

With the path attribute of the location section mentioned above, we can achieve unified management of the Web.config configuration. We can put each file or directory configuration in the root directory of the web.config file, the code is as follows:

 <configuration> <appSettings/> <connectionStrings/> <location Path = "Register.aspx" > <system.web> <authorization> <allow users= "*"/> </a uthorization> </system.web> </location> <location path = "Manageadmin" > <system.web&
      Gt <authorization> <allow roles= "Administrators" ></allow> <deny users= "*" ></deny
    > </authorization> </system.web> </location> <location path = "Manageusers" > <system.web> <authorization> <allow roles= "Users" ></allow> <deny user
    s= "*" ></deny> </authorization> </system.web> </location> <system.web> <!--Place the contents of the original root directory web.config, not listed--> </system.web> </configuration> 

End:

This thoroughly straighten out the process of form verification, found a lot of practical skills, the middle of a lot of references to the article, but also through the reflector to see the specific implementation of the source code. Feel a lot of harvest, the biggest harvest is not only to know the problem, but also to know the reason why, to have a ask why net win.

If you have any questions, not only to find solutions, there is time to best from the theory to the bottom of the code are well over, to their level of improvement has a great help.

The above asp.net to achieve form certification some of the use of the skills (must read) is a small series to share all the content, I hope to give you a reference, but also hope that we support the cloud habitat community.

Related Article

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.