Talking about asp. net Forms Authentication Detailed Explanation

  • 2021-09-04 23:53:19
  • OfStack

When doing a website, you will use the function of user login. For some sensitive resources, we only want authorized users to be able to access them, which requires user authentication. For beginners, user login information is usually stored in Session, which is what I did when I first came into contact with asp. net. When I store user information in Session, It is common to encounter Session loss, which leads to users not being able to access authorized resources normally. The security problem when maintaining the user's login status is endless. In fact, in asp. net, we have a better solution, that is, to authorize the user through Forms authentication. This method can easily maintain the user's login status (if the user wants to do this), convenient user authorization configuration, enhanced security and other benefits. No more nonsense, let's do a simple use

Before doing the example, let's define the following user class, named SampleUser, with the following code:


public partial class SampleUser
  {
    string username;
    public string UserName
    {
      get { return username; }
      set { username = value; }
    }

    string userpwd;
    public string UserPWD
    {
      get { return userpwd; }
      set { userpwd = value; }
    }

    public override bool Equals(object obj)
    {
      SampleUser other = obj as SampleUser;
      if (other == null || other.UserName != this.UserName)
        return false;
      return true;
    }
  }

  public partial class SampleUser
  {
    public static List<SampleUser> userList = new List<SampleUser> {
      new SampleUser() { UserName = "01", UserPWD = "123"}, 
      new SampleUser() { UserName = "02", UserPWD = "123" }, 
      new SampleUser() { UserName = "03", UserPWD = "123" }, 
      new SampleUser() { UserName = "04", UserPWD = "123" }, 
    };

    public static SampleUser GetUser(string userName)
    {
      return userList.Find(u=>u.UserName == userName);
    }
  }

In the class SampleUser, two fields, UserName and UserPWD, are defined to store the user's login name and password information, respectively. In the other part of the SampleUser class, we provide a static class table for users to replace the user information stored in the database, and a method GetUser to obtain the user information.

In this example, we demonstrate that the user must log in to access the resources of the website, and if not, navigate the user to the login. aspx page.

Step 1: Add configuration information to web. config to indicate that the Web site should use Forms authentication, specify the login page and the default login-successful jump page, and then specify to deny access to unlogged users. The code is as follows:


<authentication mode="Forms">
   <forms loginUrl="~/Login.aspx" defaultUrl="~/Default.aspx" />
  </authentication>
  <authorization>
   <deny users="?"/>
  </authorization>

After completing this step, we open the Default. aspx page again. If we don't log in, the page will be navigated to the Login. aspx page. Our purpose of step 1 has been achieved.

Step 2, complete the page logic of Login. aspx. Add two TextBox controls to the page to enter the user name and password; Add 1 CheckBox control to choose whether to keep login status; Add an Button control to respond to the user's login operation. The corresponding code is as follows:


<fieldset>
    <legend> User login </legend>
    <div>
       User name: <asp:TextBox ID="txtUserID" runat="server" Width="150" /><br /><br />
       Dense &nbsp;&nbsp;&nbsp; Code: <asp:TextBox ID="txtUserPWD" runat="server" TextMode="Password" Width="150" /><br /><br />
      <asp:CheckBox ID="cbSaveUserName" runat="server" Checked="true" Text=" Maintain login status " />
    </div><br />
    <asp:Literal ID="ltMessage" Text="" runat="server" Visible="false" />
    <br />
    <p>
      <asp:Button ID="btnLogin" Text=" Landing " runat="server" OnClick="btnLogin_Click" />
    </p>
  </fieldset>

Next, complete the background code and add the background processing method of login button: verify the user name and password, and if the verification passes, create an authentication ticket for the user name and add it to the Cookie of the response. The code is as follows:


protected void btnLogin_Click(object sender, EventArgs e)
    {
      string userID = this.txtUserID.Text.Trim();
      string userPWD = this.txtUserPWD.Text.Trim();

      SampleUser userEx = SampleUser.GetUser(userID);
      if (userEx == null)
      {
        ltMessage.Text = " User does not exist! ";
        ltMessage.Visible = true;
        return;
      }

      if (userEx.UserPWD != userPWD)
      {
        ltMessage.Text = " Wrong username or password, please re-enter! ";
        ltMessage.Visible = true;
        return;
      }

      // Add tickets and navigate users to the default page 
      FormsAuthentication.RedirectFromLoginPage(userEx.UserName, this.cbSaveUserName.Checked);
    }

After completing this step, we have completed the function of simple Froms verification. Run the program, and you will find that there is a problem here! ! !

Did you find out? When we were navigated to login. aspx, the style of this page was lost! This is because we have restricted the access to the resources of the whole website. If we don't log in, users can't access the. aspx page, even the css file and js file. Obviously, this is not what we want, because these resources are not sensitive resources. Usually, we want to restrict access to files in a partial folder, not the entire Web site. For example, we allow access restrictions only to pages under the User folder, because this folder contains private information of users, which is sensitive. How can this be achieved?

In order to complete the demonstration sub-directory verification, we added an User folder and two pages UserInfo. aspx and UserLogin. aspx in the project. UserInfo. aspx is used to display user information, and its business logic is not what we care about. UserLogin. aspx page is used to let users log in, and the code is almost identical to Login. aspx page.

Step 1: Modify the Web. config file to allow anonymous users to access system resources.


 <authorization>
   <allow users="?"/>
  </authorization>

Step 2: Add an Web. config file under the User folder, modify the code, and deny anonymous users access to resources under the folder.


   <authorization>
    <deny users="?"/>
   </authorization>

After completing these two steps, when we visit UserInfo.aspx, if we don't log in, we will be navigated to the ~/User/UserLogin.aspx page, and when we log in, we will be navigated to the ~/User/UserInfo.aspx page. At this point, our landing page style has not been lost, which means that our configuration file is working.

Next, we want to display the user name and password of the logged-in user on the UserInfo. aspx page (this is done solely to demonstrate how to obtain the logged-in user data, and usually the user's password is not displayed). After logging in, the user's bill information is encrypted and stored in Cookie. In this bill, there is the name information of the logged-in user. We can get the complete user information by obtaining the user name in the bill.

To display user information, we put two Label controls in the page with the following code:


<h2>
<p> User name: <asp:Label ID="lblUserName" Text="" runat="server" /></p>
<p> Dense &nbsp;&nbsp;&nbsp;&nbsp; Code: <asp:Label ID="lblUserPWD" Text="" runat="server" /></p>
</h2>

Then, in the Load method of the page, we get and display the user information:


if (this.Context.User != null && this.Context.User.Identity != null && this.Context.User.Identity.IsAuthenticated)
{
  SampleUser user = SampleUser.GetUser(this.Context.User.Identity.Name);
  if (user != null)
  {
    this.lblUserName.Text = user.UserName;
    this.lblUserPWD.Text = user.UserPWD;
  }
}

Run our code again. When the user logs in (if the login state is maintained, even if the browser is closed and reopened), we can get the Name of the logged-in user, thus obtaining the user's object.

If you want to log out, we only need to delete the ticket information saved in Cookie. This function Forms verification has been completed for us, and the code is very simple:


FormsAuthentication.SignOut();    // Exit login 

In this article, role validation is not covered, because it is not flexible to specify roles in the configuration file, and if roles are maintainable in the program, then our designation here is useless. Interested friends can learn by themselves, and it is not complicated. At the end of this article, a detailed description of the configuration of Forms verification in Web. config is attached:


<forms 
   name="name" 
   loginUrl="URL" 
   defaultUrl="URL"
   protection="[All|None|Encryption|Validation]"
   timeout="[MM]"
   path="path"
   requireSSL="[true|false]"
   slidingExpiration="[true|false]">
   enableCrossAppRedirects="[true|false]"
   cookieless="[UseUri|UseCookie|AutoDetect|UseDeviceProfile]" 
   domain="domain name"
   ticketCompatibilityMode="[Framework20|Framework40]">
   <credentials>...</credentials>
 </forms>
name: Specifies the HTTP Cookie to be used for authentication. If you are running more than one application on one server and each application requires only 1 Cookie, you must configure the Cookie name in the Web. config file for each application. The default value is ". ASPXAUTH". loginUrl: Specifies the URL for login to which the request is redirected if no valid authentication Cookie is found. The default value is login. aspx. defaultUrl: Defines the default URL for redirection after authentication. The default value is "default. aspx". protection: Specifies the type of encryption used by Cookie, if any. The default value is All. timeout: Specifies the elapsed time, in integer minutes, before Cookie expires. If the SlidingExpiration property is true, the timeout property is a sliding value and expires after the specified time (in minutes) after the last request was received. To prevent compromising performance and avoid issuing multiple browser alerts to users who turn on Cookie alerts, Cookie is updated when more than half of the specified time elapses. This may lead to impaired accuracy. The default value is "30" (30 minutes). path: Specifies the path for the Cookie emitted by the application. The default value is slash (/), because most browsers are case sensitive, and if the path case does not match, the browser will not send back Cookie. requireSSL: Specifies whether an SSL connection is required to transport the authentication Cookie. The default value is False. slidingExpiration: Specifies whether adjustable expiration times are enabled. Adjustable expiration resets the current authentication time for Cookie to expire on each request received during a single session. The default value is True. enableCrossAppRedirects: Indicates whether the authenticated user is redirected to URL in another Web application. The default value is False. cookieless: Defines whether to use Cookie and the behavior of Cookie. The default value is UseDeviceProfile. domain: Specifies the optional domain set in the outgoing Forms authentication Cookie. This setting takes precedence over the fields used in the httpCookies element. The default value is an empty string (""). ticketCompatibilityMode: Specifies whether Coordinated Universal Time (UTC) or local time is used for the ticket expiration date in Forms authentication. The default value is Framework20.

Child element credentials: Allows the option to define name and password credentials in the configuration file. You can also implement a custom cryptographic schema to control authentication using an external source, such as a database.


Related articles: