A working demo of this code can be found here. This only uses the Custom authentication. However, the demo allows you to simply move to Windows authentication.

Introduction

I've been developing a website where I wanted to use Windows authentication but had to cater for browsers that didn't support it. I looked for a possible solution and realized that you could merge Forms and Windows authentication. However, I didn't find a solution that fully met my needs, so I decided to develop my own solution.

How it works

Configuration

The XML code below is placed in the project's web.config file. This is the standard method of configuring the project for Forms authentication.

To set the permissions of a sub directory or file within the web project, the authorization information is enclosed within location tags. The example below is the code used within the demo project supplied. It sets the authorization for the 3 private pages denying all users except for those who are grouped within the stated roles. You can also specify individual users by using the name attribute.

IUserAuthenticator

All authenticators must implement the IUserAuthenticator interface in order to be used by the solution. A base authenticator class is implemented and the WindowsUserAuthenticator is also implemented. All you have to do is extend these classes and add your custom authentication and roles, or if you are using Windows authentication, just add your custom roles. In order to allow the Windows authenticated code to have custom roles, the WindowsPrincipal object is extended and a StringCollection is used to hold the roles.

The Authenticate method returns a UserAuthenticationData object which holds all the required data to re-authenticate the user on the next server round trip. This includes:

Name

Domain

Custom Roles

If the user is successfully authenticated

If Windows authentication is being used

User's Windows authentication token

This UserAuthenticationData is serialized and saved within the Forms cookie.

Re-Authentication

Within the project's Gobal.asaxFormsAuthentication_Authenticate or Application_AuthenticateRequest methods, the following line of code is required to re-authenticate the user.

ExtendedFormsAuthentication.ReAuthenticate(Context);

If Windows authentication is used, a new identity is created from the UserAuthenticationData token value, and if custom authentication is used then a generic identity is created. The custom roles are also added at this stage.

Code access

As well as restricting access to locations within the web project, this method also allows you to place access security on methods or classes. The demo code below only allows those users that meet the requirements in terms of username or roles to access the method. If the user is not authorized then a SecurityException is thrown.

Mentions

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Nice solution, but one thing worries me.
You are relying on passing an IntPtr to a user object invoked by a COM call...
Now I agree that this seems to work in a test environment, but can you always guarantee that this IntPtr will be valid when replayed
Don't know enough about the implementation to be sure, but surely this IntPtr token could be freed or reused between calls. Will it always be guaranteed to point to the same user, or even to a user at all? Would a seg fault not be possible?

Could you please clarify why this approach is guaranteed to be consistent?

I am a newbie to ASP.net, I am using C# and trying to create a login page that authenticates the username and password again a Windows account using IIS. I then wish the user to be redirected to a "Menu screen if sucessful and if unsucessful passed back to the login screen. Any help would be greatly appreciated.

What I like in Form authentication is that if session gets expire user is redirected automatically to login page, and I want similar to be done in Windows Authentication as well. I do not want to write some session validation on every page if windows authentication is used.

In your web.config and login in on the login page with: FormsAuthentication.RedirectFromLoginPage(userName, bool persistInCookie);

On two occasions I have been asked [by members of Parliament], 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. - Charles Babbage

Your setup file is missing ExtFormsAuth.sln (Project file); aslo I'd add a menu item short cut to Project file to the setup. I created one and the project looks good. Thanks for the Code; I'm going to start using it, been doing the old ASP tricks to long.