Active Directory Membership Provider
ASP.NET 2.0 supports a provider-based model for a number of application services including membership. The membership provider is therefore a component that defines the contract between ASP.NET applications and the repository of membership information. Among other things, the contract includes methods to validate users' credentials; change and reset passwords; and create, find, and delete user accounts.
The ActiveDirectoryMembershipProvider provider manages storage of membership information in Active Directory and Active Directory Application Mode (ADAM) user stores. When using the Active Directory provider, you specify the connection string in the web.config file along with valid credentials to access the Active Directory server. If you do not specify account credentials, Active Directory will use the credentials of the ASP.NET worker process.
You can use ActiveDirectoryMembershipProvider also in an Active Directory scenario where multiple domains are defined. Suppose you have two domains, each with a connection string entry in <connectionStrings> pointing to the specific user database. You define an instance of the Active Directory provider for each domain to support. Each entry will have different settings for its connection string and perhaps administrative account.
<providers> <add name="TestDomain1" type="System.Web.Security.ActiveDirectoryMembershipProvider, ..." connectionStringName="TestDomain1ConnString" connectionUsername="TestDomain1\Admin" connectionPassword="..." /> <add name="TestDomain2" type="System.Web.Security.ActiveDirectoryMembershipProvider, ..." connectionStringName="TestDomain2ConnString" connectionUsername="TestDomain2\Admin" connectionPassword="..." /> </providers>The user must indicate the domain in the login page along with credentials. Once you know the user's domain, you change the validation code of the login page as follows:
MembershipProvider domainProvider; if (domainName == "TestDomain1") domainProvider = Membership.Providers["TestDomain1"]; else if (domainName == "TestDomain2.test.com") domainProvider = Membership.Providers["TestDomain2"]; if (domainProvider.ValidateUser(userName, pswd) { : }
In general, the two predefined membership providers serve the vast majority of the cases. However, a custom membership system is reasonable if you want to use a non-Active Directory Lightweight Directory Access Protocol (LDAP) provider for authentication, a local or remote Web service, or in general, a completely custom validation algorithm.
Here's what you can follow:
- Created a new web site.
- Added a web.config file.
- Set the authentication type to "Forms"
- Added a connection string pointing to my Active Directory store. This was one of the parts I had trouble with, since I wasn't very familiar with LDAP syntax. The fully-qualified domain name for my domain controller was win2k3.vstsb2.local (I know, not very creative), while the domain was vstsb2.local. So the successful connection string section in web.config looks like this:
<connectionStrings>
<add connectionString="LDAP://win2k3.vstsb2.local/CN=Users,DC=vstsb2,DC=local"
name="ADConnString"/>
</connectionStrings>
- Then I added the following Membership section (note that this is a very simple implementation, and omits many of the optional attributes):
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
<providers>
<add name="AspNetActiveDirectoryMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider,
System.Web, Version=2.0.3600.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ADConnString"
connectionUsername="vstsblocal\Administrator"
connectionPassword="password"/>
</providers>
</membership>
- Next, I added a new folder to the site, named it "protected" (the name is arbitrary), and added a web.config to this folder with an authorization section denying access to anonymous users.
- Finally, I added a page to the new folder that writes out the name of the current user, and added a login page at the root level with a Login control to perform the authentication.
In addition to my musings above, there's some good coverage of this provider in the security article I pointed to earlier this week (see the authentication section).
A couple of other notes:
- With the syntax above for the membership provider configuration, you'll need to log in using the User Principal Name (UPN) rather than the typical DOMAIN\user syntax used for Windows authentication. The UPN syntax is basically user@domain (note that there may be more to it than that...UPN is something I only read up on today, so I'm hoping my explanation is adequate <g>). So for my example above, the user Andrew would log in using andrew@vstsb2.local as the username, and then the password as normal.
- If you'd prefer to use the SAM account name instead of the UPN, you'll need to add the following attribute to the <membership> element:
attributeMapUsername="SAMAccountName" - Once having added the above attribute, you should be able to log in using the username alone.