ASP.NET: Using Forms Authentication in ASP.NET


Previous Topic Previous Next Topic Next
Xoc Software
Training
RVBA Conventions
Maya Calendar Program
Company Information
Tools
ASP.NET and Other Tips
.NET: Debugging Designer Features of a Custom Control in Visual Studio
.NET: Setting the Default Font in a Windows Mobile/Compact Framework Custom Control
.NET Fixing C# XML Comments so they Work in Windows XP SP2
.NET: Getting and Setting the Application Version Number
.NET: Getting the Path of the Executing Assembly
.NET: Retrieving Assembly Attributes
.NET: Setting the RootFolder to Other Values in the FolderBrowserDialog in .NET
.NET: Sizing Columns in a ListView Control in .NET
.NET: Using Remoting in .NET
ASP.NET: Constructing a Graphic on the Fly in ASP.NET
ASP.NET: Controlling Caching in ASP.NET Web Forms
ASP.NET: How to use the FrontPage Server Extensions with ASP.NET
ASP.NET: Seeing What is in the ViewState in ASP.NET Web Forms
ASP.NET: Using Forms Authentication in ASP.NET
ASP.NET: View Trace Information on your ASP.NET Web Pages
ASP: Create XML from an ADO query
ASP: Detect Incomplete Loads
ASP: Including an ASP.NET Web Page In a Classic ASP Web Page
ASP: Process .HTM Files with Scripts and Server Side Includes
ASP: QuickSort Algorithm
ASP: Retrieve all server variables from IIS
ASP: Send Email from Active Server Page
HTML: How to Create a Non-Scrolling Region in HTML
IE: Allowing Only Certain ActiveX Controls to Run in Internet Explorer
IIS: Creating a web site for testing in IIS Server
IIS: Creating Multiple Web Sites within IIS on Windows 2000 and Windows XP Professional
IIS: IIS/Visual InterDev Problems and Fixes
IIS: Redirect a domain such as xoc.net to www.xoc.net
SQL Server: Execute SQL Server Updategram
Web Design: Design for People with Disabilities
Web Design: Keep a Web Page out of the Google Cache
Windows: Get HTTP Header of a Web Page using Telnet
Windows: Testing Domain Names without DNS
Windows: Using Hosts File to Access Web Sites with XP SP2
Windows: Windows XP Command Line Tools
Windows Mobile: Reprogramming the Push-to-Talk Button on the AT&T Tilt
Articles
Miscellaneous
Downloads
Links
Search
Email

Other Xoc managed sites:
http://grr.xoc.net
http://www.986faq.com
http://www.mayainfo.org
https://mayacalendar.xoc.net
http://www.yachtslog.com

There are times when you want to validate users hitting a web site on your own rather than using Windows or Passport authentication. That requires forms based security. This article shows you how to implement Forms Based Authentication.

Hitting any web page on the site will automatically redirect to the login form. When the login form has authenticated the user, it will automatically redirect back to the originally requested page. Failure to log in will prohibit the user from hitting the originally requested page.

Each example below is shown in both Visual Basic .NET and C#. Use the appropriate code for the language you are using.

In the web.config file in the root of the web site, insert this XML:

<authentication mode="Forms">
    <forms name="login" loginUrl="login.aspx" />
</authentication>

<authorization>
    <allow roles="bigboss" />
    <allow roles="wimpyuser" />
    <allow users="admin" />
    <deny users="*" />
</authorization>

Change the rules to give permissions to the proper users and roles. You may create a different web.config and its authorization section in each subdirectory with different rules.

In the global.asax file, insert this code:

[vb.net]
Imports System.Security.Principal
Imports System.Web.Security

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
    ' Fires upon attempting to authenticate the use
    If Not (HttpContext.Current.User Is Nothing) Then
        If HttpContext.Current.User.Identity.IsAuthenticated Then
            If TypeOf HttpContext.Current.User.Identity Is FormsIdentity Then
                Dim fi As FormsIdentity = CType(HttpContext.Current.User.Identity, FormsIdentity)
                Dim fat As FormsAuthenticationTicket = fi.Ticket

                Dim astrRoles As String() = fat.UserData.Split("|"c)
                HttpContext.Current.User = New GenericPrincipal(fi, astrRoles)
            End If
        End If
    End If
End Sub

[c#]
using System.Security.Principal;
using System.Web.Security;

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
	//Fires upon attempting to authenticate the use
	if (!(HttpContext.Current.User == null))
	{
		if (HttpContext.Current.User.Identity.IsAuthenticated)
		{
			if (HttpContext.Current.User.Identity.GetType() == typeof(FormsIdentity))
			{
				FormsIdentity fi = (FormsIdentity) HttpContext.Current.User.Identity;
				FormsAuthenticationTicket fat = fi.Ticket;

				String[] astrRoles = fat.UserData.Split('|');
				HttpContext.Current.User = new GenericPrincipal(fi, astrRoles);
			}
		}
	}
}

Create a Web Form named login.aspx, set the style to Flow Layout, and put this onto the page:

<table height="66%" width="100%">
    <tr>
        <td align="middle">
            <table id="loginbox" width="300" class="itemstyle">
                <tr>
                    <td id="login" align="middle" colspan="3">Login</td>
                </tr>
                <tr>
                    <td>Username:</td>
                    <td><asp:textbox id="txtUsername" tabindex="4" runat="server" 
                    columns="12"></asp:textbox></td>
                    <td valign="center" align="middle" rowspan="2">
                        <asp:button id="btnLogin" runat="server" text="Login" 
                        cssclass="button"></asp:button></td>
                <tr>
                    <td>Password:</td>
                    <td><asp:textbox id="txtPassword" runat="server" columns="12" 
                    textmode="Password"></asp:textbox></td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td colspan="2"><asp:label id="lblError" runat="server" 
                    forecolor="Red" visible="False">Not a valid username or password.</asp:label>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

In the CodeBehind for login.aspx, put this code:

[vb.net]
Imports System.Web.Security

Private Sub btnLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
 Handles btnLogin.Click
    If ValidateUser(txtUsername.Text, txtPassword.Text) Then
        FormsAuthentication.Initialize()
        Dim strRole As String = AssignRoles(txtUsername.Text)

        'The AddMinutes determines how long the user will be logged in after leaving
        'the site if he doesn't log off.
        Dim fat As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
         txtUsername.Text, DateTime.Now, _
         DateTime.Now.AddMinutes(30), False, strRole, _
         FormsAuthentication.FormsCookiePath)
        Response.Cookies.Add(New HttpCookie(FormsAuthentication.FormsCookieName, _
         FormsAuthentication.Encrypt(fat)))
        Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, False))
    Else
        lblError.Visible = True
    End If
End Sub

Private Function ValidateUser(ByVal strUsername As String, ByVal strPassword As String) _
 As Boolean
    'Return true if the username and password is valid, false if it isn't
    Return CBool(strUsername = "admin" AndAlso strPassword = "password")
End Function

Private Function AssignRoles(ByVal strUsername As String) As String
    'Return a | separated list of roles this user is a member of
    If txtUsername.Text = "admin" Then
        Return "bigboss|wimpyuser"
    Else
        Return String.Empty
    End If
End Function

[c#]
using System.Web.Security;

private void btnLogin_Click(object sender, System.EventArgs e)
{
	if (ValidateUser(txtUsername.Text, txtPassword.Text))
	{
		FormsAuthentication.Initialize();
		String strRole = AssignRoles(txtUsername.Text);

		//The AddMinutes determines how long the user will be logged in after leaving
		//the site if he doesn't log off.
		FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1, 
			txtUsername.Text, DateTime.Now, 
			DateTime.Now.AddMinutes(30), false, strRole, 
			FormsAuthentication.FormsCookiePath);
		Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, 
			FormsAuthentication.Encrypt(fat)));
		Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
	}
	else
		lblError.Visible = true;
}

private Boolean ValidateUser(String strUsername, String strPassword)
{
   //Return true if the username and password is valid, false if it isn't
	return ((strUsername == "admin") && (strPassword == "password"));
}

private String AssignRoles(String strUsername)
{
	//Return a | separated list of roles this user is a member of
	if (txtUsername.Text == "admin")
		return "bigboss|wimpyuser";
	else
		return String.Empty;
}

Change the ValidateUser and AssignRoles to do lookups into a database or other data store instead of the hardcoded validation and role assignment shown.

On each page on the site, you will need a way to log out. Simply put a hyperlink to the logout page:

<asp:HyperLink id="hlLogout" runat="server" 
NavigateUrl="logout.aspx">Logout</asp:HyperLink>

The logout.aspx page should have this on it:

<table width="100%">
    <tr>
        <td align="middle">
            You have been logged out.
            <asp:hyperlink id="hlLogin" runat="server" 
            navigateurl="default.aspx">Log back in.</asp:hyperlink>
        </td>
    </tr>
</table>

The CodeBehind for the logout page should include this:

[vb.net]
Imports System.Web.Security

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
 Handles MyBase.Load
    Session.Abandon()
    FormsAuthentication.SignOut()
End Sub

[c#]
using System.Web.Security;

private void Page_Load(object sender, System.EventArgs e)
{
	// Put user code to initialize the page here
	Session.Abandon();
	FormsAuthentication.SignOut();
}

You can put things that are only allowable to certain roles on your web page by using code like this:

[vb.net]
hlAdmin.Visible = Page.User.IsInRole("bigboss")

[c#]
hlAdmin.Visible = Page.User.IsInRole("bigboss");

Top