(c) 2002 Visual Studio Magazine
Fawcette Technical Publications

Issue: August 2002
Section: Secure Your Web Apps
Author: Timothy M. Chester

C#	Accept and Validate User Credentials
Listing 1	The CreateAccount.aspx page contains this code. This page accepts user credentials and validates them against a XML file.  Use the FormsAuthentication() class to alert ASP.NET that a successful validation has occurred, and that the user can browse the application. 

<%@ Page language="c#" trace="true"%>
<%@ import namespace='System.Web.Security'%>
<%@ import namespace='System.Xml'%>
<html>
	<head>
		<title>Forms Authentication Sample</title>
	</head>
	<body>
		<h1>Please enter your username and 
			password</h1>
		<p><asp:Label id="Msg1" runat="server" 
			ForeColor="red"/></p>
		<form runat='server'>
			<table>
				<tr>
					<td>Your Username:</td>
					<td><asp:TextBox TextMode=
						"SingleLine" 
						id="username" runat="server" 
							Width="150"/></td>
				</tr>
				<tr>
					<td>Your Password:</td>
					<td><asp:TextBox 
						TextMode="Password" 
						id="password" runat="server" 
						Width="150"/></td>
				</tr>
			</table>
		<p><asp:Button Text="Begin Session" 
				runat="server" 
				OnClick="AuthenticateUser" 
				CausesValidation="false"/></p>
		<h1>Or, create your own account here!</h1>
		<p><asp:Label id="Msg2" runat="server" 
			ForeColor="red"/></p>
		<table>
			<tr>
				<td>Your First Name:</td>
				<td>
					<asp:TextBox TextMode=
						"SingleLine" 
						id="realFirstName"
						Width="150" runat="server"/>
					<asp:RequiredFieldValidator 
						id="Required1" 
						ControlToValidate=
							"realFirstName" 
						Text="Required Field!"
						runat="server"/>
				</td>
			</tr>
			<tr>
				<td>Your Last Name:</td>
				<td>
					<asp:TextBox TextMode=
						"SingleLine" 
						id="realLastName"
						Width="150" runat="server"/>
					<asp:RequiredFieldValidator 
						id="Required2" 
						ControlToValidate=
							"realLastName" 
						Text="Required Field!"
						runat="server"/>
				</td>
			</tr>
			<tr>
				<td>Your Email Address:</td>
				<td>
					<asp:TextBox TextMode=
						"SingleLine" id="realEmail"
						Width="150" runat="server"/>
						<asp:RequiredFieldValidator 
							id="Required3" 
							ControlToValidate=
								"realEmail" 
							Text="Required Field!"
							runat="server"/>
				</td>
			</tr>
			<tr>
				<td>Enter a Username:</td>
				<td>
					<asp:TextBox TextMode=
						"SingleLine" 
						id="realUserName"
						Width="150" runat="server"/>
					<asp:RequiredFieldValidator 
						id="Required4" 
						ControlToValidate=
							"realUserName" 
						Text="Required Field!"
						runat="server"/>
				</td>
			</tr>
			<tr>
				<td>Enter a Password:</td>
				<td>
					<asp:TextBox TextMode=
						"SingleLine" 
						id="realPassword"
						Width="150" runat="server"/>
					<asp:RequiredFieldValidator 
						id="Required5" 
						ControlToValidate=
							"realPassword" 
						Text="Required Field!"
						runat="server"/>
				</td>
			</tr>
		</table>
		<p><asp:Button Text="Create Account" 
			runat="server" OnClick=
			"CreateAccount"/></p>
		</form>
	</body>
</html>
<script runat="server">
	//subprocedure that runs whenever the page 
	//executes
	void Page_Load()
	{
		//clear out all my labels so that old
		//messages are cleared out
		Msg1.Text = "";
		Msg2.Text = "";
	}
	
	//method to create an account when the create 
	//account button is pressed
	void CreateAccount(Object sender, EventArgs 
		eventArgs)
	{
		//first load your user's document
		//into an xml document
		XmlDocument x = new XmlDocument();
		x.Load("c:\\users\\users.xml");

		//make sure that the username doesn't exist 
		//previously.
		XmlNode xy = x.SelectSingleNode
			("/users/user[name='" + 
			realUserName.Text + "']");
			
		if (xy == null)
		{
			//this means that we haven't gotten a 
			//match for the name so let's create a 
			//new user element and add it to the 
			//tree
			XmlNode n = x.CreateElement("user");
			XmlNode n1 = x.CreateElement("name");
			n1.InnerText=realUserName.Text;
			n.AppendChild(n1);
			
			XmlNode n2 = 
				x.CreateElement("password");
			n2.InnerText=FormsAuthentication.
				HashPasswordForStoringInConfigFile
				(realPassword.Text,
				"sha1");
			n.AppendChild(n2);
			
			XmlNode n3 = 
				x.CreateElement("lastName");
			n3.InnerText=realLastName.Text;
			n.AppendChild(n3);

			XmlNode n4 = 
				x.CreateElement("firstName");
			n4.InnerText=realFirstName.Text;
			n.AppendChild(n4);

			XmlNode n5 = x.CreateElement("email");
			n5.InnerText=realEmail.Text;
			n.AppendChild(n5);
			
			XmlNode branch = 
				x.SelectSingleNode("/users");
			branch.AppendChild(n);
			
			//save the new xml user data back
			//to a file
			x.Save("c:\\users\\users.xml");
			
			Session["name"] = realUserName.Text;

			//then, you can simply redirect them 
			//back to the page they started from
			FormsAuthentication.RedirectFromLoginPage(
				realUserName.Text, false);
		}
		else
		{		
			//if we get here the username exists 
			//previously
			Msg2.Text = 
				"This username already exists!";
		}
	}

	//method which can be used to authenticate 
	//each user
	void AuthenticateUser(Object sender, EventArgs 
		eventArgs)
	{
		//write some code here to//authenticate 
		//against your user.xml file located in 
		//c:\users
		//first load the user information file into 
		//an xml document
		XmlDocument x = new XmlDocument();
		x.Load("c:\\users\\users.xml");

		//see if you get a match for the username 
		//and//the hash of the password
		XmlNode xy = x.SelectSingleNode
			("/users/user[name='" + username.Text + 
			"'][password='" 
			+ FormsAuthentication.
				HashPasswordForStoringInConfigFile
				(password.Text, "sha1")
			+ "']");
			
		if (xy != null)
		{		
		
			Session["name"] = username.Text;
		
			//we got a match for the username and 
			//password//so let them into the system
			FormsAuthentication.
				RedirectFromLoginPage(username.Text, 
				false);
		
		}
		else
		{
			Msg1.Text="Error: Unknown 
				username/password combination";
		}
}
</script>
