Using ADAM with ActiveDirectoryMembershipProvider for Forms Authentication

I’m going to take a bit of a detour from discussion of the specific content of Keith Brown’s paper and look at how to set up authentication using Active Directory Application Mode (ADAM) with the ActiveDirectoryMembershipProvider. Much has been written about using the SQL and AD membership providers and some regarding the use of ADAM as the identity store. So my intent here is not to re-write what is already available, but more to stitch together some of these excellent resources (create a blog mashup if you will) and add a few things around this content that further extends the developer experience with ADAM. For those that may not know, Active Directory Application Mode is Microsoft’s standalone lightweight directory service that is on par with Active Directory’s reliability, scalability, replication capability and performance ability. Therefore, it can serve well as a high performance LDAP identity store for distributed applications. With its ease of schema extensibility, it can readily serve as the repository for personalization data in Web portal and other scenarios as well.

Step 1: Get ADAM Installed
That said, let’s get after it. First you will need to get the ADAM install. If you are doing this exercise on Windows XP (SP1 or later) or Windows Server 2003, you can get the ADAM download here. For Windows Server 2003 R2, ADAM can be installed through Add/Remove Programs, Windows Components. The ADAM Step-by-Step Guide is located here. The Step-by-Step Guide is a full-bodied reference for getting up and running, but it’s overkill for our needs. Therefore, for a quick setup guide for our purposes follow steps 1 and 2 only on Erlend Oftedal’s post, Making ADAM work with ASP.NET 2.0 on Windows XP. You will notice in step 2.14 that he shows how to configure ADAM to not require a secure connection for setting passwords. Follow these instructions. It makes it more convenient for testing only but should not be used for production environments. You can refer to his post Using SSL with ADAM at a later time if you would like to set it up. Go ahead and setup ADAM. Generally, you can spin up an ADAM installation in 10 minutes or less, but it may take a bit longer if you are working through it for the first time. 

Step 2: Understand the Context
Like I mentioned, I do not want to reproduce content here but you must have a solid basis for what we’re going to do with ADAM. Therefore, to provide context the How To: Use Forms Authentication with Active Directory in ASP.NET 2.0 by Patterns & Practices serves as the model for this exercise. So, read through this document for background prior to doing the hands-on below. We will borrow from it and follow its basic pattern, but will tweak the implementation just a bit for ADAM.

Step 3: Hands-on, Create a Web Application
1. Fire up VS 2005 and create a new ASP.NET Web site called FormsAuthADAM.
2. To help us down the road, create two new folders. In the Solution Explorer, Right-click on the ...\FormsAuthADAM\ Website, choose New Folder and name it Authenticated. Repeat this step and name the new folder NonAuthenticated.
3. Drag-and-drop the Default.aspx file into the Authenticated folder.
4. Add a new Web form in the Authenticated folder called Login.aspx.
5. Add a login control to Login.aspx and set the DisplayRememberMe property to False.
6. Add a new Web form in the NonAuthenticated folder called CreateUser.aspx.
7. Add a CreateUserWizard control to CreateUser.aspx.
8. Browse the ContinueDestinationPageUrl property and select Authenticated/Login.aspx. Also set the CancelPageDestinationUrl to the same. In either case, this will send the user back to the login page.
9. Now, to complete the navigation for the Login control on the Login.aspx page. Click the Login control and set the CreateUserText property to “Create New User”.
10. Browse the CreateUserUrl property and select NonAuthenticated\CreateUser.aspx. Browse DestinationPageUrl and select Authenticated\Default.aspx.
11. Right-click on the ...\FormsAuthADAM\ Website and select Property Pages. Click on “Start Options”, Select “Specific page:” and Browse to Authenticate\Default.aspx.

Step 4: Configure the Web Application to use ADAM (the basics)
1. In the Solution Explorer, right-click on the ...\FormsAuthADAM\ Website. Select Add New Item…, Web Configuration File.
2. In the web.config file replace this line”
        <authentication mode="Windows" />
with
  <authentication mode="Forms">
   <forms
       loginUrl="authenticated/Login.aspx"    name="FormsAuthADAMCookie"
       timeout="10" />
  </authentication>

3. In the web.config file immediately following </system.web>, add the following two <location> elements to provide path-level authorization to the Web pages.

  <location path="authenticated">
    <system.web>
      <authorization>
        <deny users="?"/>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>

  <location path="nonauthenticated">
    <system.web>
      <authorization>
        <allow users="?"/>
      </authorization>
    </system.web>
  </location>

Step 5: Configure ASP.NET for ADAM Membership (the basics)
1. In the web.config file, replace
 <connectionStrings/>
with
  <connectionStrings>
    <add name="ADAMConnectionString" connectionString="LDAP://localhost:50000/OU=Users,O=TestDirectory" />
  </connectionStrings>

2. Add the following <membership> element immediately following </authentication>.

<membership defaultProvider="MyADAMMembershipProvider">
<providers>
<add name="MyADAMMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADAMConnectionString" connectionUsername="CN=ADAMAdmin,OU=Users,O=TestDirectory" connectionPassword="myADAMAdminPassword" connectionProtection="None" enableSearchMethods="true"/>
</providers>
</membership>

3. Lastly, we need to have something to display on the Default.aspx page once an authenticated user reaches it. Here we will borrow the code from the Patterns and Practices article mentioned above. Go to the Design View of the Default.aspx page and double-click on the design surface. Once in the View Code window, paste the following code inside the Page_Load event.

  Response.Write("Hello, " + Server.HtmlEncode(User.Identity.Name));
  FormsIdentity id = (FormsIdentity)User.Identity;
  FormsAuthenticationTicket ticket = id.Ticket;
  Response.Write("<p/>TicketName: " + ticket.Name );
  Response.Write("<br/>Cookie Path: " + ticket.CookiePath);
  Response.Write("<br/>Ticket Expiration: " + 
                  ticket.Expiration.ToString());
  Response.Write("<br/>Expired: " + ticket.Expired.ToString());
  Response.Write("<br/>Persistent: " + ticket.IsPersistent.ToString());
  Response.Write("<br/>IssueDate: " + ticket.IssueDate.ToString());
  Response.Write("<br/>UserData: " + ticket.UserData);
  Response.Write("<br/>Version: " + ticket.Version.ToString());

4. Now, compile and run the application. If prompted to configure the application for debugging, click yes. Once the Logon page loads, click the Create User link. On the CreateUser page, enter a new User Name, Password, fake email address and click the Create User button. Click Continue on the confirmation page to proceed to the login page. Login using the credentials of your newly created user. Create more users at will.

That’s it!! This gets you up and running using ADAM as the highly scalable identity store for your Web application(s). In my next blog I'll continue this mashup approach, but we'll continue to build on this "single, concept unifying" application. I will take you through the more advanced steps of adding attributes to your ADAM’s schema so you can store a user’s question and answer to enable password resets, etc. But this should certainly get you rolling for now!