Meditation and Mindfulness for Software / IT Professionals. Conducted by Bipin Joshi in Thane. Read more...

Using Windows and Forms Authentication Together

Introduction

ASP.NET provides two main ways to secure your web applications. They are - Windows authentication and Forms authentication. Windows authentication uses windows users names and passwords to authenticate them where as Forms authentication typically uses user ids and passwords stored in some database. One of the drawback of windows authentication is that it pops up a 'gray window' when user wants to access the web site. This makes the login screen 'misfit' with rest of the design of the site. Also, you can not provide a way to 'logout' the user. These issues can be handled by using windows authentication and forms authentication together. This article shows how to do that.

Step by step

In the following sections I will explain how to use windows and forms authentication together. Following steps are involved in the process:
  • Create a web project in VS.NET
  • Modify web.config and enable forms authentication
  • Create a login form
  • Create windows identity and principal based on user id and password entered
  • Set current user's principle to this newly created windows principal
  • Issue forms authentication cookie
  • In Logout page or button remove this authentication cookie

Namespaces Involved

Following namespaces are required to work with our example:
  • System.Runtime.InteropServices
  • System.Security.Principal
  • System.Web
  • System.Web.Security
You might be wondering why interop namespace is needed here. The reason is - we will be using some APIs to actually log on the user. This functionality is not available via any other built-in classes.

What is identity?

Identity is what the name implies. It is identification of the user. For example WindowsIdentity class represents a windows user.

What is principal?

Identity along with role is called as principal. WindowsPrincipal represents a windows user and its associated roles.

How ASP.NET stores user details?

ASP.NET allows you to probe for identity of current user via Context object. For example Context.User.Identity represents the identity of the current user. You can check the user name, whether he is authenticated etc. using this object.

Setting forms authentication in web.config

First of all you need to modify your web.config to enable forms authentication
    <authentication mode="Forms">
    <forms name="myform" loginUrl="login.aspx"></forms>
    </authentication> 

Creating a login form

Next, create a login form (login.aspx) that will allow user to enter User ID and Password. In the click event of the form's OK button write following code:
if (ValidateUser(txtUserID.Text,txtPassword.Text))
{
	FormsAuthentication.SetAuthCookie
	(Context.User.Identity.Name,false);
	if(Request.QueryString["ReturnUrl"]==null)
		Response.Redirect("webform2.aspx");
	else
		Response.Redirect
		(Request.QueryString["ReturnUrl"]);
}
else
	lblError.Text="Login Failed";
Here, we have passed the entered user id and password to a function called ValidateUser(). This function is heart of the entire process and will be explained next. As in normal forms authentication we issue authentication cookie using FormsAuthentication class.

Validating User

In order to validate user against windows users we need to call a Win32 APIs. This API should be declared in the class as shown below. Add this code in login form's code behind. You can also create it as a separate class if you wish.
[DllImport("C:\\WINDOWS\\System32\\advapi32.dll")] 
public static extern bool
LogonUser(String lpszUsername, 
String lpszDomain, 
String lpszPassword, 
int dwLogonType, 
int dwLogonProvider, 
out int phToken); 
As you can see we are going to use an API called LogonUse that logs the supplied user. It will return false if we supply invalid user id and password combinations.

The ValidateUser function looks like this:

public bool SetLogin(string uid,string pwd)
{
	try
	{
		int token1; 
		bool loggedOn = 
		LogonUser(uid,".",pwd,2,0,out token1); 
		IntPtr token2 = new IntPtr(token1); 
		WindowsIdentity wi = 
		new WindowsIdentity(token2); 
		WindowsPrincipal wp = 
		new WindowsPrincipal(wi); 
		HttpContext.Current.User = wp; 
		return true;
	}
	catch(Exception exp)
	{
		return false;
	}
}
Here, we have called LogonUser function with user id, password and collected the windows authentication token back. (Please refer to platform SDK help for details about various parameters) Then we create windows identity based on this token. The windows principal is then constructed based on this user identity. Now, we need to change ASP.NET user to our user. This is accomplished by changing User property of current Context to newly formed principal.

The sign out process is same as in typical forms authentication i.e. you call FormsAuthentication.SignOut() method.

Note: Calling LogonUser API on Win2k requires a highly privileged account. This restriction is not applicable for Windows XP and Windows 2003.

Summary

In this article we saw how to use windows authentication and forms authentication together. We saw how to accomplish this with WIn32 API - LogonUser(). This allows us to avoid the 'gray' login box and use our own login form instead.



Bipin Joshi is a software consultant, an author and a yoga mentor having 21+ years of experience in software development. He conducts online courses in ASP.NET MVC / Core, jQuery, and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced Yoga way of life he also teaches Meditation to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 22 Jun 2003



Tags : ASP.NET Web Forms Security Configuration