Wire IIS7 Basic Authentication to Authenticate against custom provider

The best custom basic authentication out there is at http://custombasicauth.codeplex.com/

But many people have told me that they don’t want to write iis extensions modules etc. So here is the simplest one, just implement ihttpmodlue

1.    Create a class library project called it Company.HttpModules
2.    I add the a class called RevBasicAuthenticationModule
3.    Below is the Code for the class

Imports System.Web
Imports System.Security.Principal
Imports System.Text

Public Class RevBasicAuthenticationModule
Implements IHttpModule

Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

End Sub

Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.AuthenticateRequest, AddressOf OnEnter
End Sub

Private Sub OnEnter(ByVal sender As Object, ByVal e As EventArgs)
Dim application As HttpApplication = DirectCast(sender, HttpApplication)
If Not Authenticate(application.Context) Then
application.Context.Response.Status = “401 Unauthorized”
application.Context.Response.StatusCode = 401
application.Context.Response.AddHeader(“WWW-Authenticate”, “Basic realm=My Company”)
application.CompleteRequest()
End If
End Sub

Public Shared Function Authenticate(ByVal context As HttpContext) As Boolean
‘Enable this if you are using ssl. Which you should
‘If Not HttpContext.Current.Request.IsSecureConnection Then
‘    Return False
‘End If

If Not HttpContext.Current.Request.Headers.AllKeys.Contains(“Authorization”) Then
Return False
End If

Dim authorizationHeader As String = HttpContext.Current.Request.Headers(“Authorization”)

Dim principal As IPrincipal = Nothing
If GetPrincipal(authorizationHeader, principal) Then
HttpContext.Current.User = principal
Return True
End If
Return False
End Function

Private Shared Function GetPrincipal(ByVal authorizationHeader As String, ByVal principal As IPrincipal) As Boolean
Dim credentials = GetAuthorizationHeader(authorizationHeader)
If credentials IsNot Nothing AndAlso ValidateUser(credentials, principal) Then
Return True
End If

principal = Nothing
Return False
End Function

Private Shared Function GetAuthorizationHeader(ByVal authorizationHeaderInfo As String) As String()
‘Get Header info.
If authorizationHeaderInfo Is Nothing OrElse authorizationHeaderInfo.Length = 0 OrElse Not authorizationHeaderInfo.StartsWith(“Basic”) Then
Return Nothing
End If

‘ The Credentials are seperated by ‘:’ and are Base64 encoded
Dim EncodedCredentials As String = authorizationHeaderInfo.Substring(6)
Dim credentials As String() = Encoding.ASCII.GetString(Convert.FromBase64String(EncodedCredentials)).Split(New Char() {“:”c})

If credentials.Length <> 2 OrElse String.IsNullOrEmpty(credentials(0)) OrElse String.IsNullOrEmpty(credentials(0)) Then
Return Nothing
End If

Return credentials
End Function

Private Shared Function ValidateUser(ByVal creds As String(), ByVal principal As IPrincipal) As Boolean
If creds(0) = “Rev” AndAlso creds(1) = “Rev” Then
principal = New GenericPrincipal(New GenericIdentity(“Rev”), New String() {“Administrator”, “User”})
Return True
ElseIf creds(0) = “Ram” AndAlso creds(1) = “Ram” Then
principal = New GenericPrincipal(New GenericIdentity(“Ram”), New String() {“User”})
Return True
Else
principal = Nothing
Return False
End If
End Function

End Class

4.    Added a empty asp.net website to the solution

5.    Add reference to the Company.httpModules

6.    Edit web.config

<system.webServer>
<modules>
<add name=”Company.httpModules” type=”Company.httpModules.RevBasicAuthenticationModule”/>
</modules>
<security>
<authorization>
<add accessType=”Allow” users=”” roles=””/>
</authorization>
</security>-
</system.webServer>

7.    Important make sure Anonymous Authentication is enabled and the rest are disabled for that application

image

8.    That is it you have a successful custom basic authentication. You can implement your own validate user how you want.
9.    But remember the authentication will take place for every request. So you have to use a mechanism to create a token or  cache credentials
10.    In the Custom Basic Authentication code on codeplex created by Dominick Baier has a cache mechanism which is good and can be used here

Advertisements

Custom Basic Authentication for IIS7

Installing and Using Custom Basic Authentication for IIS7.
1.    Download the code from http://custombasicauth.codeplex.com/.
2.    Open visual studio command prompt by right clicking run as administrator.
3.    Cd to the folder where you unzipped the downloaded source.
4.    In the output folder there is Install command file. Edit this file in notepad.
5.    Remove “rem” from line 16 rem iisschema.exe /install CustomBasicAuthentication_schema.xml.
6.    Remove “rem” from line 20 i.e rem IisRegMgmt CustomBasicAuth LeastPrivilege.CustomBasicAuthentication.Management.CustomBasicAuthenticationModuleProvider LeastPrivilege.CustomBasicAuthentication.Management.dll
7.    Save the file
8.    Run Install.cmd from VS cmd prompt

What happens when you run the install.cmd
1.    The 3 dlls will be added to the GAC
2.    When the command “iisschema.exe /install CustomBasicAuthentication_schema.xml” is executed 2 things happen.
•    CustomBasicAuthentication_schema will be copied to C:\Windows\System32\inetsrv\config\schema folder
•    <section name=”customBasicAuthentication” overrideModeDefault=”Allow” allowDefinition=”Everywhere” /> will be added to
<sectionGroup name=”system.webServer”>
<sectionGroup name=”security”>
<sectionGroup name=”authentication”>
Section in applicationHost.config file
3.    When IisRegMgmt is run it edit administration.config file.
a.    <add name=”CustomBasicAuth” type=”LeastPrivilege.CustomBasicAuthentication.Management.CustomBasicAuthenticationModuleProvider, LeastPrivilege.CustomBasicAuthentication.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f20dc168dfd54966″ />  to the  </moduleProviders>

b.    To    <location path=”.”><modules><add name=”CustomBasicAuth” /></modules>

4.    Open an application in inetmgr. Double click Authentication

image

5.    You should see Custom Basic Authentication

How to use it

1.    Create an empty asp.net website.
2.    Edit web.config, Add
<system.webServer>
<validation validateIntegratedModeConfiguration=”false”/>
<modules>
<remove name=”ScriptModule”/>
<add name=”ScriptModule” preCondition=”managedHandler” type=”System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>
<add name=”CustomBasicAuthentication” type=”LeastPrivilege.CustomBasicAuthentication.CustomBasicAuthenticationModule, LeastPrivilege.CustomBasicAuthenticationModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=F20DC168DFD54966″/>
</modules>
To System.webserver,modules section
3.    Add
<security>
<authentication>
<customBasicAuthentication enabled=”true” realm=”Your Company Name” providerName=”default” cachingEnabled=”true” cachingDuration=”15″ requireSSL=”false”/>
</authentication>
</security>
</system.webServer>
4.    You will need to hook up your custom provider. To Test I created a class library project. Called Company.Security.Provider. Added a class calledMemberProvider.vb
5.    Add refrence to system.web
6.    In the class Imports System.Web
7.    And Inherits System.Web.Security.MembershipProvider

image

8.    The only method I implement was ValidateUser
Public Overrides Function ValidateUser(ByVal username As String, ByVal password As String) As Boolean
If username = “rev” And password = “rev” Then
Return True
Else
Return False
End If
End Function
9.    Here I intend to hook up to my active directory module
10.    In the web project add reference to this class library.
11.    Edit the web.config file, add the default  provider in system.web section

<system.web>
<membership defaultProvider=”Company.Security.Provider”>
<providers>
<clear/>
<add name=”Company.Security.Provider” type=”Company.Security.Provider.MemberProvider”/>
</providers>
</membership>

12.    That’s it, you have custom basic authentication working