Active Directory in Generated Applications: Simple Authentication

“Integrate Active Directory with an Iron Speed Designer generated application.”

—Jim Murphy, Owner of River City Software Development LLC

Business Need

Securing an application is important. Though Iron Speed Designer’s Role-Based Security Wizard forms the foundation of application security, many companies require additional features. For instance, some companies need an application that will not prompt the user for a user name and password. Rather, when the application loads, it should automatically identify the user and sign them into the application. This requires integrating Active Directory into the application.

There are a number of different ways to integrate Active Directory with an Iron Speed Designer generated application. In this article, we’ll focus on ‘simple’ authentication based on the user’s Active Directory (Windows) user name. Our solution will easily allow users to be seamlessly signed into the application without having to type their password.

In future articles, we’ll discuss more complicated business requirements involving the use of an LDAP server.

Prerequisites

It is assumed that you are familiar with the basic features of Iron Speed Designer and have made several applications. Also, a fair understanding of how the Role-Based Security Wizard works is required. More information relating to the use of the Role-Based Security Wizard can be found here.

Definitions

a) Authentication: Verifying a user’s identity and which role(s) they belong to. Usually done by prompting the user for their user name and password, then comparing to an authority such as a database table or Active Directory list.

b) Authorization: Controlling the already-authenticated user’s access to a given resource.

Step 1 - Database

Fig. 1 - Database schema. This indicates that each User can have multiple Roles.

Notice the Users table has a UserName and Password field. These fields will be used by Iron Speed Designer’s Role-Based Security Wizard. Our custom code will use only the UserName field.

Fig. 2 - Users database table contents. This table contains a few users’ names and their passwords that we’ll use to sign the user into our application.

Step 2 - Virtual Directory and Security Settings

Ensure Microsoft IIS’s Virtual Directory settings are configured to provide your application with the Windows account name.

Fig. 3

In IIS’ Virtual Directory Properties, navigate to the Directory Security tab and click Edit under the Anonymous access and authentication control tab.

Fig. 4

Ensure Anonymous Access is disabled and Integrated Windows authentication is enabled. These options enable the application’s custom code to retrieve the user’s Windows account user name.

Ensure the application’s Authentication Mode in the web.config is "Windows":

<authentication mode="Windows" />

Step 3 - Modifying Your Application using Iron Speed Designer

After running the Role-Based Security Wizard and rebuilding your application, open the sign-in page (..\Security\SignIn.aspx) in Iron Speed Designer. (Fig. 3)

Fig. 5 - SignIn page. We are now ready for Iron Speed Designer to make the appropriate code customizations.

Iron Speed Designer has a great feature that automatically plumbs the basic code for the major event handlers without us having to memorize the syntax of how to hook up our own event handler. This can be accessed from your application’s Documentation.

Pull down the "Customize" menu (next to Build, etc.) and select "Customize Your Application's Documentation..." which will display a page listing the major events and describing their functionality. (Fig. 4)

Fig. 6 - Application documentation. This explains what the SignIn page’s Load event is for. It also has a feature to have Iron Speed Designer plumb the basic code shell where our customizations will go.

By right-clicking the Page’s Load routine in the tree view on the left hand side, then selecting "Insert MyLoad Method...", Iron Speed Designer automatically adds in a new MyLoad EventHandler for us (Fig. 5). The MyLoad event is fired when the page loads, before it is displayed. Just before the page is displayed, we 'hook' in to the MyLoad EventHandler and write our own code to do the actual work. This way, the code is processed before the user sees the page so we can automatically identify the user and sign them in.

Fig. 7 – Empty MyLoad EventHandler. We just added to the existing code so the EventHandler is fired when the page initializes. It is currently empty.

Step 4 - Adding the Code in Visual Studio

The last thing we need to do is write our code within the MyLoad EventHandler. This is where it may be helpful to open the project in Visual Studio or a similar product, so as to take advantage of IntelliSense, debugging and other helpful features. Be sure to save so the new code shell appears when we open the page in Visual Studio. Take note of the ‘active’ page – this is where our code shell was created. This is the page that we need to open in Visual Studio. The active page in our example is SignIn.aspx.cs.

The following code is verbosely commented for additional clarity.

Contents of MyLoad in C#:

// Set this up because we'll need Iron Speed to set the
// appropriate error later if there is a problem.
string errorMessage = "";
bool isSignedIn = false;


// First, pull out the network username which includes the
// domain or computername (e.g. JIMLAPTOP\Jim).
string userName = HttpContext.Current.User.Identity.Name;

// Next, fetch a Users record from the Users database table
// where the username matches this user's name.
UsersRecord userRec = UsersTable.GetRecord("UserName = '" +
	userName + "'");

// If a valid user exists with this network name, we will have

// a non-null record.
if (userRec != null)
{
	// found this user on the list. Grab the existing Password
	// from the database table's record. This password has no
	// relation to the users Active Directory network password.
	string password = userRec.Password;

	// Tell Iron Speed to SignIn this user using their username

	// and password. Iron Speed will 'initialize' all of the
	// security settings for this user, fetch and save their
	// roles, etc. If there is a problem, Iron Speed Designer
	// will put the error message in the errorMessage variable
	// for us so we can display it, log it, etc.
	isSignedIn = this.SystemUtils.SetLoginInfo(userName, password,
	  ref errorMessage);

	if (isSignedIn)

	{
		// SignIn worked, go 'back' to the regular start page
		// (the one that, because the user wasn't signed in,
		// redirected the user to the signin page to begin with)
			this.RedirectBack();
	}
	else
	{
	this.RedirectToForbiddenPage();

	}
}
else
{
	// User Not found with this name in the system - redirect
	// to the forbidden page.
	this.RedirectToForbiddenPage();
}

Contents of MyLoad in Visual Basic .NET:

' Set this up because we'll need Iron Speed to set the
' appropriate error later if there is a problem.
Dim errorMessage As String = ""
Dim isSignedIn As Boolean = False

' First, pull out the network username which includes the
' domain or computername (e.g. JIMLAPTOP\Jim).

Dim userName As String = HttpContext.Current.User.Identity.Name

' Next, fetch a Users record from the Users database table
' where the username matches this user's name.
Dim userRec As UsersRecord = UsersTable.GetRecord("UserName = '" + _
	userName + "'")

' If a valid user exists with this network name, we will have
' a non-null record.
If (userRec IsNot Nothing) Then

	' found this user on the list. Grab the existing Password
	' from the database table's record. This password has no
	' relation to the users Active Directory network password.
	Dim password As String = userRec.Password

	' Tell Iron Speed to SignIn this user using their username
	' and password. Iron Speed will 'initialize' all of the
	' security settings for this user, fetch and save their
	' roles, etc. If there is a problem, Iron Speed Designer

	' will put the error message in the errorMessage variable
	' for us so we can display it, log it, etc.
	isSignedIn = Me.SystemUtils.SetLoginInfo(userName, password, _
		errorMessage)

	If (isSignedIn) Then
		' SignIn worked, go 'back' to the regular start page
		' (the one that, because the user wasn't signed in,
		' redirected the user to the signin page to begin with)

		Me.RedirectBack()
	Else
		Me.RedirectToForbiddenPage()
	End If
Else
	' User Not found with this name in the system - redirect
	' to the forbidden page.
	Me.RedirectToForbiddenPage()
End If

Build and Run your application.

Because the user is not signed in, Iron Speed Designer automatically redirects the user from the Start Page to the Sign In page. Before the Sign In page appears, our new code grabs the Active Directory user’s name, retrieves their Password from the User record, and tells Iron Speed Designer to sign them in. After a successful sign in process, the user is redirected back to the application’s Start Page. All of this happens so quickly that the user is unaware that a sign in process ever took place.

Conclusion

This Article addresses one user requirement: automatically sign the user in based on their Active Directory user name. By creating a database table for Windows user names, changing the appropriate web security settings and writing our custom code, we have created an ‘automatic’ user sign-in experience.

There are many other scenarios involving Active Directory. For instance, perhaps the security requirements demand the user to be prompted for their Windows user name and password, so as to authenticate both against an Active Directory or Novel eDirectory LDAP server. It is also possible to integrate this feature with Iron Speed Designer, this will be the subject of a future article.

This sample project can be downloaded at http://www.rcsdev.com/files/ADIntegration.zip. This zip file contains C# and Visual Basic .NET versions of the sample application, as well as a database script that creates a Users, Users_Role and Role table and populates them with sample data.

About the Author

Jim Murphy is the Owner and Chief Application Designer and Developer for River City Software Development LLC. Jim has been programming professionally for over 16 years in fields that include Health Care, Insurance, Banking/Lending, Real Estate, Oil & Gas, Manufacturing, and Government.

Jim was an early adopter of Iron Speed Designer and worked closely with Iron Speed Technical Engineers while the product was maturing. Jim’s major strengths are in Microsoft SQL Server, Microsoft Access, C#, Visual Basic .NET, XML, and Reporting.

[Contact the author]