Wednesday, June 27, 2007

Form-based Authentication in ASP.NET Samples Source Code

  by: juliet

Form-based Authentication in ASP.NET

by: juliet

It is a common need for a web site to have membership and login system, particularly when part of the web site is restricted in access by non-members. This tutorial will guide you through how to create such a form-based authentication in ASP.NET using C#.

There are totally four things you need to create in order to make a form-based authentication.

1. A database (Access 2000 or SQL server, or any RDBMS with a .NET ODBC driver) with a membership table.

2. A login web control

3. web.config file

4. The actual login page

The membership table

At least you should have a table to store member information. The table can be as simple as having only the MemberID, strUserName and strPassword fields:

-------------

tblMembership

-------------

MemberID

strUserName

strPassword

-------------

You can add any useful fields to this table for your particular need like FirstName, LastName, E-mail address, or even IPAddress for tracking purpose. To keep the problem simple, we will just keep this 3 fields in our discussion.

The login web control

Code for the login web control (login.ascx):
<%@ Control language="C#" %>
<script language="C#" runat="server">
public String BackColor = "#FFFFFF";
public String UserId {
get {
return User.Text;
}
set {
User.Text = value;
}
}

public String Password {
get {
return Pass.Text;
}
set {
Pass.Text = value;
}
}

public String BackGroundColor {
get {
return BackColor;
}
set {
BackColor = value;
}
}

public bool IsValid {
get {
return Page.IsValid;
}
}
</script>
<table style="background-color:<%=BackColor%>
;font: 10pt verdana;border-width:1;
border-style:solid;border-color:black;"
cellspacing=15 ID="Table1">
<tr>
<td><b>Login: </b></td>
<td><ASP:TextBox id="User" runat="server"/></td>
</tr>
<tr>
<td><b>Password: </b></td>
<td><ASP:TextBox id="Pass" TextMode="Password"
runat="server"/></td>
</tr>
<tr>
<td></td>
<td><ASP:Button Text="Submit"
OnServerClick="Submit_Click" runat="server"/></td>
</tr>
<tr>
<td align="center" valign="top" colspan="2">
<asp:RegularExpressionValidator id="Validator1"
ASPClass="RegularExpressionValidator" ControlToValidate="Pass"
ValidationExpression="[0-9a-zA-Z]{5,}"
Display="Dynamic"
Font-Size="8pt"
runat=server>
Password must be >= 5 alphanum chars<br>
</asp:RegularExpressionValidator>
<asp:RequiredFieldValidator id="Validator2"
ControlToValidate="User"
Font-Size="8pt"
Display="Dynamic"
runat=server>
UserId cannot be blank<br>
</asp:RequiredFieldValidator>
<asp:RequiredFieldValidator id="Validator3"
ControlToValidate="Pass"
Font-Size="8pt"
Display="Dynamic"
runat=server>
Password cannot be blank<br>
</asp:RequiredFieldValidator>
</td>
</tr>
</table>

There are a table in which are two textboxes and a button. In order for the password textbox to hide password of the user, we add the TextMode="password" attribute to the password textbox. Note that we have used 3 validator to validates the userName and password: Validator1 and Validator3 validates the password field to check for any empty password or password which are too short. Validator2 check for empty userName.

In this control, I use property to encapsulate any detail of the login control. For a detail discussion on property, read my separate tutorial: Property: Encapsulation in C#

Now, lets see the web.config file.

The web.config file
<configuration>
<system.web>
<customErrors mode="Off"/>
<authentication mode="Forms">
<forms name=".ASPXFORUM"
loginUrl="login.aspx" protection="All"
timeout="30" path="/" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
What you have to keep watch to is the lines with <authentication> and <authorization> tags.

The mode="Forms" attribute to the authentication tag indicates that form-based authentication is used in the case. The other available attributes are window (for Win NT authentication), passport(for Passport authentication) and none. The protection="All" means both encription and validation-based protection were used. The timeout="30" attribute indicates the cookie expiration period. The path attribute denotes the cookie path. The name attribute is the name of the cookie use. Lastly and the most important one is loginUrl which denotes the login page which will be re-directed to whenever authentication is needed.

For the authorization section, there is only one tag here which is <deny users="?" />. The <deny> tag here specifies that we will deny any un-authenticated user for accessing this directory and any sub-directories where this web.config file is placed. The other tag available is the <allow> tag which would be used to specify what users are allow to access in the current folder and deny access to other user instead.

The login.aspx page

Here is the complete code for the login page:
<%@ Page language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<%@ Import Namespace="System.Web.Security" %>
<%@ Register TagPrefix="MySite" TagName="Login" Src="login.ascx" %>

<script language="C#" runat="server">
private void Page_Load(Object sender, EventArgs E) {
if ((Page.IsPostBack) && (Page.IsValid)) {
string strDSN =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Membership.mdb";
string strSQL = "SELECT userName, userPassword FROM Membership
WHERE userName='" + MyLogin.UserId + "'";

OleDbConnection myConn = new OleDbConnection(strDSN);
OleDbCommand myCmd = new OleDbCommand(strSQL, myConn);
OleDbDataReader dr = null;
try {
myConn.Open();
dr = myCmd.ExecuteReader();

if(dr.Read()) {
if(dr.GetString(1).Trim() == MyLogin.Password.Trim()) {
FormsAuthentication.RedirectFromLoginPage(MyLogin.UserId, false);
}
else
Message.Text = "Sorry! Your login or password is incorrect.
<br>Please log in again.";
}
else
{
Message.Text = "Sorry! Your login or password is incorrect.
<br>Please log in again.";
}
}
catch(Exception myException) {
Response.Write("Oops. The error: " + myException.Message);
}
finally {
myConn.Close();
}
}
}
</script>
<html>
<body>
<h3>Login</h3>
<form runat="server" ID="Form1">
<asp:Label id="Message" runat="server" />
<MySite:Login id="MyLogin" BackColor="#FFFFCC" runat="server"/>
</form>
</body>
</html>

What you need to observe in this snipplet of code is the namespaces which need to be imported and the use of a web control by using the Register directive. The TagPrefix attribute is the prefix you use to specify this user control instead of the asp: tag prefix to use with web controls. TagName is the tag you use and src points to the source code of the actual user control which we had discussed before.

The database connection codings here is quite trivial, it simply query the table and see whether the user name exists in the table. If yes, the password is checked, otherwise, an error message is delivered.

The worth-noting line is:
FormsAuthentication.RedirectFromLoginPage(MyLogin.UserId, false);

This line will redirect the user to the page where he/she originally requested if he/she is successfully authenticated. The false at the end indicates that persistent cookie is not used in this case. Turn it to true if you need to use persistent cookie.

Summary:

In summary, this tutorial had guide you through the four steps you need to follow in order to make a login page for your members in your site which includes the database, the login web control, the web.config file and the actual login page.

Download

Authentication tutorial.

0 Comments: