Forms Authentication (A), Using XML

These will be a series articles about security issue of ASP.NET Authentication:

Introduction

 
After I wrote the first security article, Authentication (1): Windows Authentication, I originally planned to write other two articles to summarize Forms Authentication and Passport Authentication, then concentrate on the new, cutting edge security OAuth and OpenID Authentication. However, I found out the staff in, such as, Forms Authentication is quite huge, it is very hard to summarize this topic within one article (I do not want to just make words summary, but with sample for support), then I think I'd better to split one article into severals with each article only has one topic.  That must be fit to the SOLID principle, especially for principle one and two:
  • The Single-responsibility principle: Every class should have only one responsibility.
  • The Open–closed principle: Software entities ... should be open for extension, but closed for modification.
This way will make me easier to write the articles, and also easier for readers to read.
 
This article will be
 

A: Forms Authentication using XML

 
This simple example will demonstrate the Forms Authentication using XML (in fact, web.config here):
 
Step 1: Create an Empty ASP.NET Web App
 
We use the current version of Visual Studio 2019 16.9.4 and .NET Framework 4.8 to build the app.
  • Start Visual Studio and select Create a new project.
  • In the Create a new project dialog, select ASP.NET Web Application (.NET Framework) > Next.
  • In the Configure your new project Dialog Box, enter FormAuth for Project name
  • In the Create a New ASP.NET Web Application Dialog Box, select Empty > Create.
Note
  • You have to use empty web app template, otherwise, some logic below willnot work (the regular template associated with a RouteConfig.cs class, empty template does not have, that class makes the app routing behavior different) .
  • This example originally is from Forms Authentication In ASP.NET, you may see some detailed implementations there.
Step 2: Add three Web Forms: Login, Default, and Welcome
  • Right Click project > Add > Web Form
  • In the opened Box: specify the item name > OK
Login.aspx
  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="FormAuth.Login" %>    
  2. <!DOCTYPE html>    
  3. <html    
  4.     xmlns="http://www.w3.org/1999/xhtml">    
  5.     <head runat="server">    
  6.         <title></title>    
  7.     </head>    
  8.     <body>    
  9.         <form id="form1" runat="server">    
  10.             <h3>    
  11.       Login Page</h3>    
  12.             <table>    
  13.                 <tr>    
  14.                     <td>    
  15.           UserName:</td>    
  16.                     <td>    
  17.                         <asp:TextBox ID="UserName" runat="server" />    
  18.                     </td>    
  19.                     <td>    
  20.                         <asp:RequiredFieldValidator ID="RequiredFieldValidator1"     
  21.             ControlToValidate="UserName"    
  22.             Display="Dynamic"     
  23.             ErrorMessage="Cannot be empty."     
  24.             runat="server" />    
  25.                     </td>    
  26.                 </tr>    
  27.                 <tr>    
  28.                     <td>    
  29.           Password:</td>    
  30.                     <td>    
  31.                         <asp:TextBox ID="UserPass" TextMode="Password"     
  32.              runat="server" />    
  33.                     </td>    
  34.                     <td>    
  35.                         <asp:RequiredFieldValidator ID="RequiredFieldValidator2"     
  36.             ControlToValidate="UserPass"    
  37.             ErrorMessage="Cannot be empty."     
  38.             runat="server" />    
  39.                     </td>    
  40.                 </tr>    
  41.                 <tr>    
  42.                     <td>    
  43.           Remember me?</td>    
  44.                     <td>    
  45.                         <asp:CheckBox ID="chkboxPersist" runat="server" />    
  46.                     </td>    
  47.                 </tr>    
  48.             </table>    
  49.             <asp:Button ID="Submit1" OnClick="Login_Click" Text="Log In"     
  50.        runat="server" />    
  51.             <p>    
  52.                 <asp:Label ID="Msg" ForeColor="red" runat="server" />    
  53.             </p>    
  54.         </form>    
  55.     </body>    
  56. </html>   
Login.aspx.cs
  1. using System;  
  2. using System.Web.Security;  
  3.   
  4. namespace FormAuth  
  5. {  
  6.     public partial class Login : System.Web.UI.Page  
  7.     {  
  8.         protected void Page_Load(object sender, EventArgs e)  
  9.         {  
  10.   
  11.         }  
  12.         protected void Login_Click(object sender, EventArgs e)  
  13.         {  
  14.             if (FormsAuthentication.Authenticate(UserName.Text, UserPass.Text))  
  15.             {  
  16.                 FormsAuthentication.RedirectFromLoginPage(UserName.Text, chkboxPersist.Checked);  
  17.             }  
  18.             else  
  19.             {  
  20.                 Msg.Text = "Invalid User Name and/or Password";  
  21.             }  
  22.         }  
  23.     }  

Defaullt.aspx
  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FormAuth.Default" %>  
  2.   
  3. <!DOCTYPE html>  
  4.   
  5. <html xmlns="http://www.w3.org/1999/xhtml">  
  6. <head runat="server">  
  7.     <title></title>  
  8. </head>  
  9. <body>  
  10.     <form id="form1" runat="server">  
  11.         <div> Welcomae to Default Page!!!  
  12.         </div>  
  13.         <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Log Out" />  
  14.     </form>  
  15. </body>  
  16. </html> 
Default.aspx.cs
  1. using System;  
  2. using System.Web.Security;  
  3.   
  4. namespace FormAuth  
  5. {  
  6.     public partial class Default : System.Web.UI.Page  
  7.     {  
  8.         protected void Page_Load(object sender, EventArgs e)  
  9.         {  
  10.   
  11.         }  
  12.   
  13.         protected void Button1_Click(object sender, EventArgs e)  
  14.         {  
  15.             FormsAuthentication.SignOut();  
  16.             FormsAuthentication.RedirectToLoginPage();  
  17.         }  
  18.     }  

Welcome.aspx
  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Welcome.aspx.cs" Inherits="FormAuth.Welcome" %>  
  2.   
  3. <!DOCTYPE html>  
  4.   
  5. <html xmlns="http://www.w3.org/1999/xhtml">  
  6. <head runat="server">  
  7.     <title></title>  
  8. </head>  
  9. <body>  
  10.     <form id="form1" runat="server">  
  11.         <div> This is a Welcome Page!!!  
  12.         </div>  
  13.         <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Log Out" />  
  14.     </form>  
  15. </body>  
  16. </html> 
Step 3: Configure Forms Authentication
 
In web.config file,
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <configuration>  
  4.     <appSettings>  
  5.         <add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />  
  6.     </appSettings>  
  7.     <system.web>  
  8.         <compilation debug="true" targetFramework="4.5" />  
  9.         <authentication mode="Forms">  
  10.             <forms loginUrl="login.aspx" defaultUrl="default.aspx">  
  11.                 <credentials passwordFormat="Clear">  
  12.                     <user name="test" password="test"/>  
  13.                 </credentials>  
  14.             </forms>  
  15.         </authentication>  
  16.         <!--This section denies access to all files in this application except for those that you have not explicitly specified by using another setting. --> 
  17.         <authorization>  
  18.             <deny users="?"/>  
  19.         </authorization>  
  20.         <httpRuntime targetFramework="4.5" />  
  21.     </system.web>  
  22.     <!--This section gives the unauthenticated user access to the Default1.aspxpage only. It is located in the same folder as this configuration file.--> 
  23.     <location path="welcome.aspx">  
  24.         <system.web>  
  25.             <authorization>  
  26.                 <allow users ="*" />  
  27.             </authorization>  
  28.         </system.web>  
  29.     </location>  
  30.     <!-- This section gives the unauthenticated user access to all of the files that are stored in the Subdir1 folder. -->
  31.     <location path="subdir1">  
  32.         <system.web>  
  33.             <authorization>  
  34.                 <allow users ="*" />  
  35.             </authorization>  
  36.         </system.web>  
  37.     </location>  
  38. </configuration> 
What we did,
  • In the web.config file:
    • Configure Authentication Mode as Froms: <authentication mode="Forms">
    • Deny all files: <deny users="?"/>, except one indicated as a login file: login.aspx
    • Allow users: <allow users ="*" />, for specific page or location (folder)
  • In the login file:
    • FormsAuthentication.Authenticate Method, Validates a user name and password against credentials stored in the configuration file for an application.
  • In the default page:
    • Click the Log Out button, to log out by FormsAuthentication.SignOut();
Run the App the opened page (default) will be redirected to the login page automatically, because access is not allowed,
 
 
However,if we type the address of welcome.aspx page, we can get it without a login required, because it is accessable without a login protection:
 
 
In the login page, type in wrong username/password, or empty, you will get warning:
 
 
Type in correct one as defined in web.config file: test/test, you will log in and get:
 
 
Click Log Out button, you will log out.
 

Summary

 
This article discusses the implementation of Forms Authentication by using XML.
 
References