Figures

Figure 1 Simple Forms Authentication

PublicPage.aspx
  <html>
  <body>
    <h1>Public Page</h1>
    <hr>
    <form runat="server">
      <asp:Button Text="View Secret Message" OnClick="OnViewSecret"
        RunAt="server" />
    </form>
  </body>
</html>
<script language="C#" runat="server">
  void OnViewSecret (Object sender, EventArgs e)
  {
      Response.Redirect ("Secret/ProtectedPage.aspx");
  }
</script>

ProtectedPage.aspx
  <%@ Page Language="C#" %>
<html>
  <body>
    <h1>Protected Page</h1>
    <hr><br>
    <% Response.Write (Context.User.Identity.Name + ": "); %>
    Be careful investing your money in dot-coms.
  </body>
</html>

LoginPage.aspx
  <html>
  <body>
    <h1>Please Log In</h1>
    <hr>
    <form runat="server">
      <table cellpadding="8">
        <tr>
          <td>
            User Name:
          </td>
          <td>
            <asp:TextBox ID="UserName" RunAt="server" />
          </td>
        </tr>
        <tr>	
          <td>
            Password:
          </td>
          <td>
            <asp:TextBox ID="Password" TextMode="password"
              RunAt="server" />
          </td>
        </tr>
        <tr>
          <td>
            <asp:Button Text="Log In" OnClick="OnLogIn"
              RunAt="server" />
          </td>
          <td>
          </td>
        </tr>
      </table>
    </form>
    <hr>
    <h3><asp:Label ID="Output" RunAt="server" /></h3>
  </body>
</html>
<script language="C#" runat="server">
  void OnLogIn (Object sender, EventArgs e)
  {
      if (FormsAuthentication.Authenticate (UserName.Text,
          Password.Text))
          FormsAuthentication.RedirectFromLoginPage (UserName.Text,
              false);
      else
          Output.Text = "Invalid login";
  }
</script>

Web.config (Application Root)
  <configuration>
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="LoginPage.aspx">
        <credentials passwordFormat="Clear">
          <user name="Jeff" password="imbatman" />
          <user name="John" password="redrover" />
          <user name="Bob" password="mxyzptlk" />
          <user name="Alice" password="nomalice" />
          <user name="Mary" password="contrary" />
        </credentials>
      </forms>
    </authentication>
  </system.web>
</configuration>

Web.config (Secret Subdirectory)
  <configuration>
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</configuration>

Figure 4 User Names and Passwords Stored in a Database

LoginPage.aspx
  <%@ Import NameSpace="System.Data.SqlClient" %>
<html>
  <body>
    <h1>Please Log In</h1>
    <hr>
    <form runat="server">
      <table cellpadding="8">
        <tr>
          <td>
            User Name:
          </td>
          <td>
            <asp:TextBox ID="UserName" RunAt="server" />
          </td>
        </tr>
        <tr>	
          <td>
            Password:
          </td>
          <td>
            <asp:TextBox ID="Password" TextMode="password"
              RunAt="server" />
          </td>
        </tr>
        <tr>
          <td>
            <asp:Button Text="Log In" OnClick="OnLogIn"
              RunAt="server" />
          </td>
          <td>
            <asp:CheckBox Text="Keep me signed in" ID="Persistent"
              RunAt="server" />
          </td>
        </tr>
      </table>
    </form>
    <hr>
    <h3><asp:Label ID="Output" RunAt="server" /></h3>
  </body>
</html>
<script language="C#" runat="server">
  void OnLogIn (Object sender, EventArgs e)
  {
      if (CustomAuthenticate (UserName.Text, Password.Text))
          FormsAuthentication.RedirectFromLoginPage (UserName.Text,
              Persistent.Checked);
      else
          Output.Text = "Invalid login";
  }
  bool CustomAuthenticate (string username, string password)
  {
      SqlConnection connection = new SqlConnection
          ("server=localhost;database=weblogin;uid=sa;pwd=");
      try {
          connection.Open ();
          StringBuilder builder = new StringBuilder ();
          builder.Append ("select count (*) from users " +
              "where username = \'");
          builder.Append (username);
          builder.Append ("\' and cast (rtrim (password) as " +
              "varbinary) = cast (\'");
          builder.Append (password);
          builder.Append ("\' as varbinary)");
          SqlCommand command = new SqlCommand (builder.ToString (),
              connection);
          int count = (int) command.ExecuteScalar ();
          return (count > 0);
      }
      catch (SqlException) {
          return false;
      }
      finally {
          connection.Close ();
      }
  }
</script>

Web.config (Application Root)
  <configuration>
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="LoginPage.aspx" />
    </authentication>
  </system.web>
</configuration>

Figure 6 A Shorter-lived Cookie
  void OnLogIn (Object sender, EventArgs e)
{
    if (CustomAuthenticate (UserName.Text, Password.Text)) {
        string url = FormsAuthentication.GetRedirectUrl
            (UserName.Text, Persistent.Checked);
        FormsAuthentication.SetAuthCookie (UserName.Text,
            Persistent.Checked);
        if (Persistent.Checked) {
            HttpCookie cookie =
                Response.Cookies[FormsAuthentication.FormsCookieName];
            cookie.Expires = DateTime.Now +
                new TimeSpan (7, 0, 0, 0);
        }
        Response.Redirect (url);
    }
    else
        Output.Text = "Invalid login";
}

Figure 7 Layering Roles Onto Forms Authentication
  <%@ Import Namespace="System.Security.Principal" %>
<script language="C#" runat="server">
  void Application_AuthenticateRequest (Object sender, EventArgs e)
  {
      HttpApplication app = (HttpApplication) sender;
      if (app.Request.IsAuthenticated &&
          app.User.Identity is FormsIdentity) {
          FormsIdentity identity = (FormsIdentity) app.User.Identity;
          if (identity.Name == "Jeff")
              app.Context.User = new GenericPrincipal (identity,
                  new string[] { "Developer" });
      }
  }
</script>

Figure 8 Forms Authentication with Role-based Security

LoginPage.aspx
  <%@ Import NameSpace="System.Data.SqlClient" %>
<html>
  <body>
    <h1>Please Log In</h1>
    <hr>
    <form runat="server">
      <table cellpadding="8">
        <tr>
          <td>
            User Name:
          </td>
          <td>
            <asp:TextBox ID="UserName" RunAt="server" />
          </td>
        </tr>
        <tr>	
          <td>
            Password:
          </td>
          <td>
            <asp:TextBox ID="Password" TextMode="password"
              RunAt="server" />
          </td>
        </tr>
        <tr>
          <td>
            <asp:Button Text="Log In" OnClick="OnLogIn"
              RunAt="server" />
          </td>
          <td>
            <asp:CheckBox Text="Keep me signed in" ID="Persistent"
              RunAt="server" />
          </td>
        </tr>
      </table>
    </form>
    <hr>
    <h3><asp:Label ID="Output" RunAt="server" /></h3>
  </body>
</html>
<script language="C#" runat="server">
  void OnLogIn (Object sender, EventArgs e)
  {
      if (CustomAuthenticate (UserName.Text, Password.Text)) {
          string url = FormsAuthentication.GetRedirectUrl
              (UserName.Text, Persistent.Checked);
          FormsAuthentication.SetAuthCookie (UserName.Text,
              Persistent.Checked);
          if (Persistent.Checked) {
              HttpCookie cookie =
                Response.Cookies[FormsAuthentication.FormsCookieName];
              cookie.Expires = DateTime.Now +
                  new TimeSpan (7, 0, 0, 0);
          }
          Response.Redirect (url);
      }
      else
          Output.Text = "Invalid login";
  }
  bool CustomAuthenticate (string username, string password)
  {
      SqlConnection connection = new SqlConnection
          ("server=localhost;database=weblogin;uid=sa;pwd=");
      try {
          connection.Open ();
          StringBuilder builder = new StringBuilder ();
          builder.Append ("select count (*) from users " +
              "where username = \'");
          builder.Append (username);
          builder.Append ("\' and cast (rtrim (password) as " +
              "varbinary) = cast (\'");
          builder.Append (password);
          builder.Append ("\' as varbinary)");
          SqlCommand command = new SqlCommand (builder.ToString (),
              connection);
          int count = (int) command.ExecuteScalar ();
          return (count > 0);
      }
      catch (SqlException) {
          return false;
      }
      finally {
          connection.Close ();
      }
  }
</script>

Global.asax
  <%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Security.Principal" %>
<script language="C#" runat="server">
  void Application_AuthenticateRequest (Object sender, EventArgs e)
  {
      HttpApplication app = (HttpApplication) sender;
      if (app.Request.IsAuthenticated &&
          app.User.Identity is FormsIdentity) {
          FormsIdentity identity = (FormsIdentity) app.User.Identity;
          // Find out what role (if any) the user belongs to
          string role = GetUserRole (identity.Name);
          // Create a GenericPrincipal containing the role name
          // and assign it to the current request
          if (role != null)
              app.Context.User = new GenericPrincipal (identity,
                  new string[] { role });
      }
  }
  string GetUserRole (string name)
  {
      SqlConnection connection = new SqlConnection
          ("server=localhost;database=weblogin;uid=sa;pwd=");
      try {
          connection.Open ();
          StringBuilder builder = new StringBuilder ();
          builder.Append ("select role from users " +
              "where username = \'");
          builder.Append (name);
          builder.Append ("\'");
          SqlCommand command = new SqlCommand (builder.ToString (),
              connection);
          object role = command.ExecuteScalar ();
          if (role is DBNull)
              return null;
          return (string) role;
      }
      catch (SqlException) {
          return null;
      }
      finally {
          connection.Close ();
      }
  }
</script>

Web.config (Secret Subdirectory)
  <configuration>
  <system.web>
    <authorization>
      <allow roles="Manager" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>

Figure 9 Configuring URL Authorizations
  <configuration>
  <!— Configuration information for this directory —>
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="/LoginPage.aspx" />
    </authentication>
  </system.web>
  <!— Configuration information for the Secret directory —>
  <location path="Secret">
    <system.web>
      <authorization>
        <allow roles="Manager" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>
</configuration>

Figure 10 Attributes of <forms> Element

Attribute
Description
Default
name
Name assigned to authentication cookies
.ASPXAUTH
loginUrl
URL of the login page
login.aspx
protection
Level of protection (validation and encryption) applied to authentication cookies
All
timeout
Lifetime of session authentication tickets in minutes
30
path
Scope of authentication cookies
/