In this scenario, a protected resource, default.aspx, is requested by the client. In the security section of the configuration file, the authentication mode is set to "Cookie", so ASP+ tries to find a cookie that is attached to the request. If it finds none, it redirects the request to a login page (login.aspx). There, the client user enters the required credentials (e-mail name and password). The page compares the entered credentials to a list of credentials in an XML file. If a match is found, the request is considered authenticated and the client is redirected to the originally requested resource (default.aspx). If no match is found, the request is redirected to the add user page (adduser.aspx). There, the just-entered credentials are encoded and added to the XML file.
There are five files associated with this example — three .aspx files (default.aspx, login.aspx, and adduser.aspx) and two configuration files (both named config.web, but one is located in the application root directory and the other is located in the adduser directory). All five files will be explained in the following discussion.
You should set up this configuration file to have the following entries and place it in the application root directory (the directory in which default.aspx resides).
<configuration> <security>
<authentication mode="Cookie" />
<cookieauthentication
decryptionkey = "autogenerate"
loginurl = "login.aspx"
cookie = ".ASPXCOOKIEAUTH" />
<authorization> <deny users="?" /> </authorization> </security> </configuration>
You should set up this file to have the following entries and place it in the file containing adduser.aspx. These settings allow anyone access to this directory (assuming there are no NTFS ACLs preventing it).
<configuration> <security> <authentication mode="None" /> <authorization> <allow users="*" /> </authorization> </security> </configuration>
This is the requested, protected resource. It is a simple file that merely displays the string "Hello" plus the recorded (logged in) e-mail name, and a Signout button.
<%@ Page LANGUAGE="c#" %> <html> <head> <title>Cookie Authentication</title> <script runat=server> private void Page_Load(Object Src, EventArgs E ) { Welcome.InnerHtml = "Hello, " + Context.User.Identity.Name; } private void Signout_Click(Object sender, EventArgs E) { CookieAuthentication.SignOut(); Response.Redirect("login.aspx"); } </script> <body> <h3><font face="Verdana">Using Cookie Authentication</font></h3> <span id="Welcome" runat=server/> <form runat=server> <input type="submit" OnServerClick="Signout_Click" Value="Signout" runat="server"/><p> </form> </body> </html>
This is the file to which the request gets redirected if ASP+ does not find the cookie with the request. This URL was set up in the configuration file. A form is presented to the client user. It has two text boxes (e-mail name and password) and a submit button. The user enters the e-mail name and password, and clicks the submit button. The code then checks to see if this name and password is contained in an XML file located in this directory. If it is, then the user is connected to default.aspx. If it is not, the adduser.aspx file is called.
To implement this functionality, proceed as follows:
<%@ Page LANGUAGE="c#" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SQL" %> <%@ Import Namespace="System.Web.Security " %> <%@ Import Namespace="System.IO" %> <html> <head> <title>Cookie Authentication</title>
<script runat=server>
private void Login_Click(Object sender, EventArgs E) {
if( !Page.IsValid ) { Msg.Text = "Some required fields are missing"; return; }
String cmd = "UserEmail='" + UserEmail.Value + "'";
DataSet ds = new DataSet();
Note For the sake of simplicity, and the learning experience, the following code does not follow best design practice, in that it does not invoke any file locking or sharing flags. Also, in a real Web site, it would probably be desirable to use a relational database for the list of authenticated users.
FileStream fs = new FileStream(Server.MapPath("users.xml"), FileMode.Open,FileAccess.Read); StreamReader reader = new StreamReader(fs); ds.ReadXml(reader); fs.Close();
DataTable users = ds.Tables[0];
DataRow[] matches = users.Select(cmd);
if( matches != null && matches.Length > 0 ) {
DataRow row = users.Rows[0]; String pass = (String)row["UserPassword"]; if( 0 != String.Compare(pass, UserPass.Value, false) ) //********************************************** // If no password match is found, tell the user. //********************************************** Msg.Text = "Invalid Password: Please try again"; else //************************************************* // If a password match is found, redirect the request // to the originally requested resource (Default.aspx). //************************************************* CookieManager.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked); } else {
StringBuilder url = new StringBuilder(); url.Append("adduser/adduser.aspx?"); url.Append(Request.ServerVariables["QUERY_STRING"]); url.Append("&UserEmail="); url.Append(Server.UrlEncode(UserEmail.Value)); url.Append("&UserPassword="); url.Append(Server.UrlEncode(UserPass.Value)); Response.Redirect(url.ToString()); } } </script> <body>
<form runat=server> <h3><font face="Verdana">Login Page</font></h3> <table> <tr>
<td>Email:</td> <td><input id="UserEmail" type="text" runat=server/></td> <td><ASP:RequiredFieldValidator ControlToValidate="UserEmail" Display="Static" ErrorMessage="*" runat=server/> </td> </tr> <tr>
<td>Password:</td> <td><input id="UserPass" type=password runat=server/></td> <td><ASP:RequiredFieldValidator ControlToValidate="UserPass" Display="Static" ErrorMessage="*" runat=server/> </td> </tr> <tr>
<td>Persistent Cookie:</td> <td><ASP:CheckBox id=PersistCookie runat="server" autopostback="true" /> </td> <td></td> </tr> </table>
<input type="submit" OnServerClick="Login_Click" Value="Login" runat="server"/><p> <asp:Label id="Msg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat=server /> </form> </body> </html>
When the login page cannot find the e-mail name in the "users" XML file, it redirects the request to this page, and if the user clicks the "Add User" button, the user name and password are added to the file. This page is implemented as follows:
<%@ Page LANGUAGE="c#" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SQL" %> <%@ Import Namespace="System.Web.Security " %> <%@ Import Namespace="System.IO" %> <html> <head> <title>Cookie Authentication</title>
<script runat=server>
private void Page_Load(Object Src, EventArgs E ) {
String email = Request.QueryString["UserEmail"]; String password = Request.QueryString["UserPassword"];
if( null != email ) UserEmail.Value = email; if( null != password ) UserPass.Value = password; }
private void AddUser_Click(Object sender, EventArgs E) {
if( !Page.IsValid ) { Msg.Text = "Some required fields are missing"; return; }
DataSet ds = new DataSet();
String userFile = "../users.xml";
FileStream fs = new FileStream(Server.MapPath(userFile), FileMode.Open,FileAccess.Read); StreamReader reader = new StreamReader(fs); ds.ReadXml(reader); fs.Close();
DataRow newUser = ds.Tables[0].NewRow(); newUser["UserEmail"] = UserEmail.Value; newUser["UserPassword"] = UserPass.Value; ds.Tables[0].Rows.Add(newUser); ds.AcceptChanges();
fs = new FileStream(Server.MapPath(userFile), FileMode.Create, FileAccess.Write|FileAccess.Read); StreamWriter writer = new StreamWriter(fs); ds.WriteXml(writer); writer.Close(); fs.Close();
CookieManager.RedirectFromLoginPage(UserEmail.Value, PersistCookie.Checked); } </script> <body> <form runat=server> <div style="background:#ccccff"><h3><font face="Verdana">Add New User</font></h3></div>
<table> <tr> <td>Name:</td> <td><input id="UserEmail" type="text" runat=server/></td> <td><ASP:RequiredFieldValidator ControlToValidate="UserEmail" Display="Static" ErrorMessage="*" runat=server/> </td> </tr> <tr> <td>Password:</td> <td><input id="UserPass" type=password runat=server/></td> <td><ASP:RequiredFieldValidator ControlToValidate="UserPass" Display="Static" ErrorMessage="*" runat=server/> </td> </tr> <tr> <td>Persistent Cookie:</td> <td><ASP:CheckBox id=PersistCookie runat="server" autopostback="true" /> </td> <td></td> </tr> </table> <input type="submit" OnServerClick="AddUser_Click" Value="Add User" runat="server"/><p> <asp:Label id="Msg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat=server /> </form> </body> </html>
To see an example run that has code very similar to this example, go to the ASP+ Quick Start and run sample "Forms-based/Cookie Authentication".