Mixed Mode Authentication
page 1 of 2
Published: 03 Nov 2004
Unedited - Community Contributed
This article will demonstrate how to use Windows Integrated Authentication and Forms Authentication for one web application. Use Windows Integrated Authentication for seamless logon, and use Forms authentication for users unable to use Windows Integrated authentication (such as non-intranet users) and all with the same role-based access model.
by Paul Glavich
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 48268/ 41

Mixed Mode Authentication - Page 1

In an increasing number of the web applications that I have had to design and work on, the client has requested the best of both worlds when it comes to authentication. Ideally, they would like their intranet users to be able to seamlessly log onto the system (Windows integrated authentication) and make authorization decisions based on their domain roles as well as be able to have external parties log onto the system using standard forms authentication. In this article, I will show you one way of achieving this goal.

Note: This method assumes that cookies are allowed and enabled on the client browsers.

Assumed Knowledge

This article assumes the reader is familiar with the setup of forms authentication in ASP.NET, Windows principal objects, role based authorization, reflection, and also familiar with the setup of Windows integrated authentication using the Internet Information Services (IIS) snap-in management console.

A Common Model

In order for this mixed mode authentication scenario to work, and also to make it easy on developers, a common and familiar security model is required for authentication and, subsequently, authorization.  If we were trying to emulate Windows integrated authentication from a forms authentication-based site, it would be extremely difficult, if not impossible, to accurately mimic and obtain a user's roles from the domain in a seamless manner. It would be much easier to let Windows/IIS provide a user's roles for us in an appropriate principal object, to extract those roles, and to mimic a forms authentication process.

This method means that to the application, all users have authenticated via the forms authentication method, but that intranet users will have a larger and more specific set of roles attached with their principal object. The diagram below illustrates this.

Basic Setup

In ASP.NET, you cannot have a single application with different modes of authentication. For this to work we will need to have two applications, or in IIS terms, two virtual directories. These act as two different entry points to the same application. One is a very simple application that uses windows integrated authentication, the other is the complete/main application using forms authentication. The windows authorization site exists only for the purposes of extracting an intranet users roles and passing them to the forms authentication site. To examine this in more detail, we will begin by giving a detailed explanation of the Windows integrated authentication site/entry point.

Windows Integrated Authentication Site

As mentioned above, this site exists only to extract role information from an intranet user and pass it along to the forms authentication site. Forms authentication (for our purposes) uses cookies as the method of indicating an authenticated user. It can be configured to use cookieless mode, but we will only be using cookies in this scenario. So we will need to peform three main functions :

    1. Authenticate the user (performed automatically for us by IIS and in combination with the web.config).
    2. Extract a user's roles to pass to main application.
    3. Supply a valid forms authentication ticket to the forms authentication entry point so that the site believes we are a valid authenticated user.

Step 1 - Authenticate the User

Accomplishing Step 1 is easy. When creating the virtual directory using the IIS MMC snap-in, ensure that 'Anonoynous Access' is disabled (not checked) and that 'Integrated Windows Authentication' is checked/enabled as shown in the diagram below:

Modifying the Web.Config

We also need to ensure that the Web.Config file of our Windows authentication entry point application is set up correctly. Below is a sample of a Web.Config file. The important part is the 'authentication' element.  It must have its 'mode' set to 'Windows'.

 <authentication mode="windows">

You might be thinking, in order to get access to a Windows principal with roles, we will need to use impersonation. Well, actually, we dont. I too at first thought this, and it still obviously will work fine if we do enable impersonation, but the principal is still passed to our application at an early stage for us to work with. Within the 'Application_AuthenticateRequest' event in the Global.asax file of our application is where we will be extracting the role information. If we needed to work with the principal and have it attached to our currently running thread, then impersonation would be required.

Important Note: This application needs to exist in a virtual directory, that is a sub-directory or sub-application of the main forms authentication application. The reason for this is that both applications will need to have the same HOST name. Cookies are generated and named according to the host name they apply to. Specifying the same cookie name in code, but using different host names will cause two different cookies to be generated because of the different host names. The diagram below shows an example of how the virtual directories should be setup in the IIS manager. 

View Entire Article

User Comments

Title: MVC3 and IIS7   
Name: Paul Glavich
Date: 2012-02-08 5:36:56 PM
Hi Joe and Jeff,
It has been a very long time since I revisited this code. If I get time I will try and get it updated for the latest tech. The basic cookie principles are the same but the mechanics of MVC3/IIS7 are what would be causing it to not work.
Title: MVC3 and IIS7   
Name: Joe
Date: 2012-02-08 10:40:11 AM
I agree with Jeff. :)
Title: IIS 7   
Name: Jeff
Date: 2012-02-03 11:31:55 AM
What are the chances of getting this article updated to 2012? I find that this solution doesn't work with IIS 7 and MVC 3.
Title: HttpSessionState.Timeout   
Name: Vladimir Kelman
Date: 2009-01-05 8:08:56 AM
Hi Paul! What happens in your solution when a user which was successfully authenticated does not do anything for a time longer than HttpSessionState.Timeout? I assume that if user clicks to any internal link/button after Session was expired, she is redirected to a Form login screen and it happens regardless of was a user initially authenticated through a Windows site or through a Form site. Isn't it a problem?
Title: Re: SharePoint and Office Integration   
Name: Paul Glavich
Date: 2007-10-07 8:01:34 AM
Hi Philip,
I am not too familiar with the Sharepoint means of authentication but if office uses only integrated, it will work if the user is a member of the authenticated domain, however they may have to eneter their domain credentials as well, so the single sign on wont exactly work. You would have to intercept the auth mechanism's for both to be able to achieve the single sign on and emulate the forms auth cookie.
Title: SharePoint and Office Integration   
Name: Philip Waters
Date: 2007-10-03 2:23:34 PM
In sharepoint a web authenticated user can click on a document that is launched in the local Office Application.

For intranet users that authenticate using windows integrated authentication, i assume they will not have to authenticate a second time when they launch a document.

Is that correct?

I assume for IE 7 they will have to have *.app.domain in their trusted or local intranet sites for authentication passthrough.

Since all authentication ultimately goes through forms authentication, i'm concerned that office integration will not work seamlessly because MS Office doesn't utilize authentication that occured through a form.
Title: Re: Magic Number Issue   
Name: Paul Glavich
Date: 2007-09-03 7:45:13 AM
Hi Murali,

This code has not been tested under 2.0 and I do know that the magic number does not explicitly exist as an internal member within .Net 2. I have not yet had a chance to revap this code to 2.0 but a little playing with reflector should be able to yield the effect you desire. So I have no immediate resolution to the issue for .Net 2 is your ultimate answer.
Title: Magic Number ISSUE   
Name: Murali
Date: 2007-08-30 5:05:22 PM
I have implemented Mixed Authentication in 1.1 which works fine but i am having issue when i migrate the App from 1.1 to 2.0 the Magic Number returns nothing. Do you have any solution for this issue.

Thank you
Title: Re: Problem   
Name: Paul Glavich
Date: 2007-08-28 11:39:41 PM
Hi Monir,

Did you create the virtual directory as a sub-dir of the main site? (ie. and not as a virtual directory on its own).
Title: Problem   
Name: Monir
Date: 2007-08-28 1:50:09 AM
Hi,I am having Problem in the web site for FormAuthentication.When I entered into the Windows Authentication Site it redirects to the Form Authentication Site with cookie 'CMUCookie'.
FormsAuthentication.FormsCookieName equals to also 'CMUCookie'.But the problem is that the codes below in the global.asax in the Form Authentication Site does not execute. That is cookieFound =false. why this is happening?
I have made the virtual directory as u directed.

if (cookie.Name == FormsAuthentication.FormsCookieName)
cookieFound = true;
authCookie = cookie;
Title: Error   
Name: Ajeet
Date: 2007-07-10 9:15:18 AM
After going thru the code, it provides an error that in the global.asax of windows application "field2.SetValue(princ,40);" it throwing a null exception handling error
can you explain it
Thanks in advance
Title: Re: Single Entry   
Name: Paul Glavich
Date: 2007-05-07 5:45:53 AM
Hi Tony,

You are correct. If windows auth is used and the user is NOT a member of the domain, the credentials prompt will get shown by IE. Not much you can do to get around it. I guess you could write a handler to perhaps check for some specific header information (if you could inject it) or query information, and if present, redirect appropriately, but that implies some control over the users browsing experience which not many people have (eg. intranet users may always have a "organisation" cookie carried along that you could check for).
Title: Single Entry   
Name: Tony
Date: 2007-05-03 6:13:29 AM
Hi, I was directed here from the ASP.NET forums and unless I have miss understood (hopefully) this is not the right spot for me.

I would like a similar behaviour, but with a single entry point as my users can't be expected to know whether they are authenticated to a domain or not.

Users hitting a web set-up for Integrated Windows Authenticated would surely get a login prompt no?
Title: re: HELP!!   
Name: Paul Glavich
Date: 2007-03-25 9:30:49 PM
Hi Non IT person,

If your organisational policy is to NOT use anonymous access (which forms based auth requires) and to only use Windows auth, it makes this approach not really possible. IIS is the first port of call for requests and if it mandates windows auth only, then thats what you get.
Title: re: same thing in ASP   
Name: Paul Glavich
Date: 2007-03-25 9:28:38 PM

Well technically its possible, but with a great deal of difficulty and COM interop. I have not done this and it would require some serious investigation work to make it so. My advice... dont do it.
Title: HELP!!   
Name: Non IT person
Date: 2007-03-20 10:43:28 PM

I am trying to install an application at work which requires a mixed mode authentication... although my office server only allows for single (windows authentication). As a consequence the IT department are saying that I am unable to install the application because a mixed mode authentication process will compromise company security. I do not have an IT background and would therefore like to know whether there is a possibility to install the application without compromising company security???

Title: very good   
Name: madhu
Date: 2006-11-30 12:28:40 AM
its very nice to read ,article of this stuff
Title: same thing in ASP   
Name: Naman
Date: 2006-11-28 6:19:54 AM
Hi Paul,

I need same thing in ASP without using .NET technology. is this possible???
Title: Re: .NET Version 2.0   
Name: Paul Glavich
Date: 2006-10-15 9:43:25 PM
I haven't done much investigation with .Net 2.0 and this technique and the reflection part that you mentioned does not work is no surprise. However, if you -know- that the number of roles will remain low, then you dont really need to do this. This reflection was to cater for the number of roles that is catered for by default. Any more roles than the 'magic_number' incurs a performance hit that is dealth with differently. I'd have to crack open reflector and have a look to see what the appropriate reflection technique (if any) is required for .Net 2.0. Easiest way to tell if you need to do it is define a user with a large amount of roles (say > 50 maybe more), then use this technique to get the roles (without the MAGIC_NUMBER code) and see if you get all the roles back.
Title: .NET Version 2.0   
Name: Brian
Date: 2006-10-13 10:45:19 AM
I am trying to do pretty much exactly what you've written about except I'm doing it with .NET Version 2.0 instead of .NET Version 1.1 (v1.1.4322). My problem is when I try to GetRoles(IPrincipal princ)
FieldInfo field2 = type.GetField("MAGIC_NUMBER", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
This line of code returns field2 as null. I'm not sure if this is a Version 2.0 problem or just something else, I suspect that its a problem with trying to do it in Version 2.0 . I'm fairly inexperienced with all of this and was looking for a little help???
Title: Is the reverse possilbe   
Name: Amir
Date: 2006-09-15 1:20:11 PM
Lets say there a two web applications. One that uses windows authentication and the other that uses just annonymous. For the one that uses annonymous access we have a form that authenticates the user. Is it possible to redirect the user to the application that uses windows authentication without having to re-enter the user credentials from that application(annonymous app)? Both application sits in the website directory
Title: coder   
Name: adam
Date: 2006-08-29 4:49:41 PM
What do I have to do finally in the
Application_Authenticate Event (Forms Auth site) if the cookie is found? My site bounces me out again to the login form. I tried using:

FormsAuthentication.SetAuthCookie(formsId.Name, false);

and this seems to get the user to the windows login site original request. But is this right? Thanks in advance.
Title: Re: Charles Bretana Jr   
Name: Paul Glavich
Date: 2006-08-21 2:42:01 AM
Ofcourse. If you simply use cookies and a form based scheme to do the authentication, the windows roles dont really have any effect. If you get the user to logon via the windows auth site, you can check for the existence of a particular role, if it does not exist, then redirect to the forms auth site. Alternatively, just go straight to the forms authentication site and get them to log in. This can issue a cookie based on what they log in as and is independent of their windows identity. As long as you use forms based authentication via cookies, you should be fine.
Title: Other way around ?   
Name: Charles Bretana Jr
Date: 2006-08-19 1:09:25 PM
This may be exactly what I'm looking for, but befopre I go down this path, can you tell me if it can also be set up to work the other way? That is, as I understand it a way for a site to accept users currently logged on to their workstations, and ALSO accept those who are not, by allowing them to provide credetials via a logon form.

My requirement, otoh, is to do that, but also allow someone who IS authenitcated via Windows security to provide DIFFERENT credentials via a logon form (like the "run as" item in the Windows popup menu) and thereafter operate the web application under the credetials they provided, even though they are still logged on at their workstation under the original (different) credentials.

Use case: A Supervisor walks over to a worker bee's desk and wants to do something tha tthe worker bees credentials are not authorized for...

Can the design outlined here solve this problem as well ?
Title: Mr   
Name: Tej
Date: 2006-07-27 11:05:01 AM
Is this mixed mode authentication technique valid for asp.net 2.0?
Title: Window auth within Forms auth Question   
Name: Brian
Date: 2006-07-12 12:05:32 PM
I have application “A” that uses forms authentication and is used by internet users and intranet users. All users will be passed to a login application “B” that uses forms authentication and a database for roles then redirected back to application “A” after authentication. (users may have different roles depending on application) I don’t want intranet users to physically login if already logged onto the intranet network. Question: In the forms based login application “B”, can I get the user.identity.name using windows authentication or some other manner? If user.identity.name is found (user logged onto intranet) look it up in database for roles, if user.identity.name not found or not authorized for application “B” give them a login screen for forms authentication. Once authenticated and roles found redirect to application “B”.
Title: Cookieless Authenticatio   
Name: Robert
Date: 2006-06-21 12:47:30 PM
I need to implement a solution like this but I'm using cookieless="UseDeviceProfile". Is this still possible to use this solution or do I have to find another way?
Title: vb   
Name: justin
Date: 2006-05-18 10:08:03 AM
Is there any way someone could show me this method in VB?
Im writing my asp.net site with VB not C#
Title: Reply to all   
Name: Rajesh
Date: 2006-03-31 12:43:02 AM
It was very useful for me...
Title: Just What I Needed   
Name: John Morrill
Date: 2006-02-06 9:59:45 PM
This article was just what I needed. I my case we had a requirement that internal users should be able to access the application using Windows Authentication. Furthermore, internal user should not be prompted for their user name and password.

The problem is that Windows Authentication usually uses NTLM with Internet Explorer to automatically obtain the user credentials. Our application is on a web farm front-ended by a load balancer, but NTLM can not be used through a load balancer.

NTLM uses a persistent connection between the browser and the server. If NTLM is used with a load balancer that pools connections to the server, strange things will happen. What we needed was a load balancer friendly solution.

I used your example code, but instead of having MyWinAuthSite as a sub-directory of the MyFormsAuthSite, I was able to make it work on a different server altogether.

In your article, you state:

The reason for this is that both applications will need to have the same HOST name. Cookies are generated and named according to the host name they apply to. Specifying the same cookie name in code, but using different host names will cause two different cookies to be generated because of the different host names.

This is true, but the work around it to specify a value for the Domain property of the cookie. If you have to different sites named, MyWinAuthSite.contoso.com and MyFormsAuthSite.contoso.com, you can pass a cookie from MyWinAuthSite to MyFormsAuthSite by specifying “contoso.com” as the Domain when you create the cookie.

There is a catch. You can not use Sliding Expiration with the Forms Authentication ticket you create on MyWinAuthSite. In order to update a cookie with the domain value set, you must specify the Domain property in the server side code that updates the cookie. Since there is no way to specify to the Forms Authentication module the setting of the Domain property, there is no way for it to update the cookie.

If y
Title: Its also possible to do a forms authentication against a windows domain   
Name: Phil
Date: 2005-09-20 2:12:08 AM
Great article, I recently used it to implement an Intranet/Extranet solution for a client where we needed to allow intranet users extranet access as they wanted to access the site from home without but still wanted to use their Domain details.

I combined the solution presented here with the domain authentication DLL from http://www.ondotnet.com/pub/a/dotnet/2003/01/20/formsauthp2.html

and was able to allow intranet users to authenticate seamlessly while at work, then from home could use forms login using their domain account.
Title: Anonymous Access reply   
Name: Gaset
Date: 2005-07-22 1:46:29 AM
Ok, thank you. Now the matter is clear.
Title: Anonymous Access reply   
Name: Paul Glavich
Date: 2005-07-22 12:02:54 AM

One of main issues will be the fact that the user may get prompted with a domain logon depending on their browser settings if going to the auth site. This is kind of out of your control. Your initial suggestion of using the 401 error page may work, but only after the attempted negotiation.
Title: Anonymous Access reply   
Name: Gaset
Date: 2005-07-21 9:02:12 AM
Ok, thank you in any way. But this is not the point in my case. Entry point for both auth and not auth users must be the same, because there is no way of distinguishing them before the proper logging in. I just cannot tell auth user from not auth before their running through Windows auth application. That's it.
Title: Anonymous Access reply   
Name: Paul Glavich
Date: 2005-07-21 7:48:55 AM

I think I have mis-understood what you were after. If you have completely anonymous users, then dont bother sending them to the windows auth-site. Give them a link to the forms auth site only. Why bother with the Windows auth entry point? They are both only meant to gather auth info for the same app and it all gets encapsulated into a formsidentity anyway.
Title: Anonymous Access reply   
Name: Gaset
Date: 2005-07-21 7:01:54 AM
Paul, in any case execution won't reach this event hadler, because IIS will not authenticate anonymous user and access will be denied.
Thank you.
Title: Anonymous Access reply   
Name: Paul Glavich
Date: 2005-07-21 6:57:47 AM

Yes, I meant for the Windows Auth site only.
Title: Anonymous Access reply   
Name: Gaset
Date: 2005-07-21 5:25:22 AM
>> >>Access will be denied,isn't it?
>>To the windows site yes, but you can provide a standard >>login form on your forms auth site for them
>>to login.
But, as I have understood, anonymous user won't be able to pass Windows auth and won't get to Forms auth site... He will be displayed 401 error page.
And thus Application_AuthenticateRequest event won't be fired for Forms auth site. Or do you mean Application_AuthenticateRequest event handler for Windows auth site?
Title: Anonymous Access reply   
Name: Paul Glavich
Date: 2005-07-20 11:32:52 PM
Hi Gaset,

>> Access will be denied,isn't it?
To the windows site yes, but you can provide a standard login form on your forms auth site for them to login.

>> And if I want do redirect this user to the forms authenticated web site (without creating authentication cookie), what will be the best option? I assume that it is reasonable to set redirection in custom error page that is set in IIS. Will it be fine?

Well it will work, but I would be inclined to do it in the Global.asax
- Application_AuthenticateRequest event using some code.
Title: Anonymous Access   
Name: Gaset
Date: 2005-07-20 3:43:42 PM
And what if anonymous (not authenticated by Windows) user will try to login? Access will be denied,isn't it? And if I want do redirect this user to the forms authenticated web site (without creating authentication cookie), what will be the best option? I assume that it is reasonable to set redirection in custom error page that is set in IIS. Will it be fine?
Title: Developer   
Name: Oliver
Date: 2005-05-27 4:28:41 PM
Instead of doing reflection to copy all windows roles. The Generic Indentity all ready carries all those roles and can be used by casting it to windowsidentity and then to verify the roles. I think .Net Framework would allow the retrieval of roles with GetRolesForUser(...).

Public Shared Function IsInRole(ByVal principal As IPrincipal, ByVal role As String) As Boolean
Dim isValidRole As Boolean = False

If Not IsNothing(principal) Then
'Check if Role is on custom roles
If TypeOf principal Is GenericPrincipal Then
isValidRole = CType(principal, GenericPrincipal).IsInRole(role)
End If

If Not isValidRole Then
If TypeOf principal.Identity Is WindowsIdentity Then
Dim currentWindowsPrincipal As WindowsPrincipal
currentWindowsPrincipal = New WindowsPrincipal(CType(principal.Identity, WindowsIdentity))

isValidRole = currentWindowsPrincipal.IsInRole(role)
End If
End If

End If

Return isValidRole

End Function
Title: EASY TO GET   
Date: 2005-03-01 2:17:25 AM
Especially re: querying roles from a Wind
owsPrincipal. I had some different code that I was using for something like that whereby I grabbed
an array of field values from the WindowsBuiltInRole enum and looped through them checking:
Title: Re: Why we need two entry point   
Name: Paul Glavich
Date: 2005-01-29 12:52:14 AM
Having 2 entry points, IMHO, is a much cleaner way of dealing with the 2 separate authentication mechanisms. Also, under IIS5/5.1 (not sure about IIS6, allowing anonymous users will take precedence over the windows authentication which would never get done, where Anonymous auth is enabled so you would never get the benefit of the windows specific roles and be able to authorize against them.

I am curious if you have even done this and got it to work successfully.?
Title: Why we need two entry point   
Name: David Cao
Date: 2005-01-27 1:47:50 AM
Why we need two entry point?
another solution is :
1. In IIS, use windows authentication and allow anonymous access.
2. In Web Config, use windows authentication and allow anonymous access.
3. Use windows authentication to authenticate windows users. For anonymous users(Request.IsAuthenticated is False), redirect them to login page and authenticate them against database or other resources. Then build GenericIdentities and GenericPrincipals for them (we can still build FormsAuthenticationTicket cookies.). Then assign the GenericPrincipal to Httpcontext.Current.User. Later we may use iPrincipal and iIdentity to access either WindowsPrincipal or GenericPrincipal.
So only one entry point and no need to use reflection.
Title: Reply to Prerak   
Name: Paul Glavich
Date: 2004-11-09 5:50:59 AM
Prerak, you get the username via the following code below. It is referenced on page 2 of this article.

WindowsIdentity ident = WindowsIdentity.GetCurrent();
string userName = ident.Name;
Title: Question   
Name: Prerak
Date: 2004-11-08 12:30:08 PM

I understood most of the part, but I don't understand how do I get the "username" of the intranet user. What parameters do I need to change in order to get to the username.

Title: Reply to Prerak   
Name: Paul Glavich
Date: 2004-11-08 6:24:36 AM
The Windows auth site will be just a URL that you supply to your intranet users eg. http://your_intranet/winauth.aspx and the forms auth site URL is what will be redirected to from your auth site in code, AND it will also be the URL supplied to your anonoymous uses for logging on.
Title: I cant understand ...   
Name: Prerak
Date: 2004-11-07 4:41:08 PM
In regards to this article, my question could be stupid but I am fairly new to asp.net. I create a virtual directory with windows authentication. but I dont understand the flow, how does the page for windows login gets called, and how does the page for form login is called. Also in case of the windows authentication, after a user is authenticated how is the request Url called.Please suggest me.

Title: Another Alternative   
Name: Paul Wilson
Date: 2004-11-01 7:54:23 AM
Here's an article (of mine) that provides another option to integrate both forms and windows auth:

You'll still to query Windows roles, but that's very doable with code on the net. I personally think having two entry points, as you've done, is smoother but I was forced to create my single entry point solution for one gig. :)
Title: Nice stuff Paul...   
Name: Darren Neimke
Date: 2004-10-31 7:46:11 PM
Some interesting stuff in there and a few little gotcha's, especially re: querying roles from a WindowsPrincipal. I had some different code that I was using for something like that whereby I grabbed an array of field values from the WindowsBuiltInRole enum and looped through them checking:

if( myWindowsPrincipal.IsInRole( arrayOfValues[i] ) )
myArrayList.Add( arrayOfValues[i] ) ;

Yours is probably better I'll need to check but mine didn't have some of that magic numbers stuff and reflection.

Product Spotlight
Product Spotlight 

Community Advice: ASP | SQL | XML | Regular Expressions | Windows

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-06-17 8:27:11 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search