This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND


This article assumes you're familiar with Active Server Pages, VBScript, and Internet Information Server .
Download the code (3KB)

An Inside Look at Site Server Personalization & Membership
Robert Howard

Microsoft Site Server lets you easily build interactive, dynamic Web sites. But where do you begin? Here’s an introduction to using the Site Server personalization and membership features.
Microsoft® Site Server 3.0 and Site Server Commerce Edition 3.0 were designed to help developers build interactive, dynamic Web sites. But with an abundance of tools and options available, where do you begin? While the documentation for Site Server can seem daunting, you may be surprised by how simple and intuitive its tools really are.
      The Microsoft Management Console (MMC) is the best place to start. You may be familiar with the snap-in concept introduced with Internet Information Server (IIS) 4.0. If you aren't, suffice it to say that snap-ins are common user interface tools designed to make it easy to manage enterprise applications centrally.
      Site Server adds several new snap-ins to the MMC that ease your managerial and administrative chores by abstracting even the most rudimentary tasks into wizards. Learning the more granular details of all the new snap-ins is time-consuming but worthwhile. The Personalization & Membership and the Membership Directory Manager snap-ins provide the control and configuration options for the personalization and membership functionality in Site Server.

What is Personalization & Membership?
      The personalization feature gives the developer the ability to provide individualized views for users, based on settings that either the user or the developer can configure. This lets you target your data to your user base. For instance, you can greet every user that is a member of your site by their first name or configure your content based on user preferences.
      Membership gives users the means to access the site. By using several different authentication techniques, membership identifies users and grants them the necessary access permissions to the file system driving IIS.
      Together, personalization and membership provide a powerful infrastructure for managing and providing community among a user base. In this article I'll build upon that infrastructure by creating some Active Server Pages (ASP) that manipulate the Membership Directory Service to configure and add personalized user data.

Configuring a Site to Use Membership
      Before you implement a Personalization & Membership-based site, it is always a good idea to do some planning. Once you implement the site and realize that a particular authentication type might not work, it might be too late. Although it seems like a logical choice to use Windows NT®-style (intranet) authentication, try to plan ahead for growth and abstract your Windows NT users from your Web users—unless, of course, you are implementing on an intranet and are comfortable with the existing user structure.
      Before you begin building your membership site, you have to determine what type of membership to use. In addition to storing all of the user and site information, the Membership Server also provides access control based on security settings assigned to users, groups, and items. Access to the Membership Server and file system itself is determined by either existing Windows NT accounts (intranet authentication), or accounts that reside only in the Membership Server (membership authentication). Membership authentication uses a Windows NT proxy user to access the file system. Either way, the Windows NT file system is accessed with a valid Windows NT user.
      When using membership authentication, you need to add the proxy group created on the Windows NT system that corresponds to the public membership group (which will be named site_[Membership Server Name]_public) to the file system you want your users to access. The Membership Proxy User (MemProxyUser) will then be granted rights to file system items by the Access Control Lists (ACL) and Access Control Entries (ACE) set by their rights and/or groups assigned to them in the Membership Server. When the user requests a system resource, the MemProxyUser will be granted access to the item according to the rights of the membership user. Membership authentication works best for Internet sites since the number of users can grow dramatically and the security is abstracted away from the normal Windows NT access list.
      If you plan to use personalization and membership on your intranet and already have everyone's rights assigned to your file system, you should use intranet authentication. This way you can reap all of the benefits from personalization and membership without having to rework your file system.

Membership Directory and LDAP Protocol
      The technology that drives the membership component of Personalization & Membership relies heavily on a Membership Directory to store and retrieve all of its information. The Membership Directory is the Microsoft implementation of a directory service that supports Lightweight Directory Access Protocol (LDAP).
      A directory service is an information store or database for structured organizational data. It is optimized for reads, not writes. You may already be familiar with directory services if you have worked with Domain Name Services (DNS). A DNS is simply a directory service that maps IP addresses to domain names.
      With the release of Windows NT 5.0, Microsoft will make even heavier use of their implementation of the directory service. The Active Directory is expected to replace the functionality of the registry found in current versions of Windows® since it is much more scalable, extensible, and supports distributed security.
      The Membership Directory supports several protocols, one of which is LDAP. LDAP provides the means to communicate with the Membership Directory. The protocol consists of five models: data, organizational, security, functional, and topological. Although each model is important, only the data and organizational models are discussed in this article because together they define entries and the relationships that entries have to one another.
      The data model defines the attribute entries to be made; these attributes in turn define the properties of the objectClass. The objectClass determines the attributes of an entry. For example, an objectClass of HockeyPlayer might consist of the attributes numTeeth, numPenMinutes, and numGoals.
      While the data model defines the objects, the organizational model defines the relationships that the objects have to one another. Each entry is defined in the directory tree, and except for the root object, each has a parent object. The ability to define entries makes the combination of the Membership Directory and LDAP extensible and scalable.
      A special class that I used in my sample code is the Members container. The Members container is an abstraction of an objectClass or a classSchema (similar to a base class in C++) from which new classes are derived. The Members container has certain preassigned attributes (also known as schemaAttributes), such as first name, last name, and password. Each new member that is created in the Members container becomes a class of a member uniquely identified by a globally unique identifier (GUID) and common name (CN) with its own data for each attribute. For a brief list of some common attributes in the members container, see Figure 1.
      Although this was a relatively brief overview of the Membership Directory and LDAP, a good understanding of what's going on behind the scenes will help you down the road in your design decisions.

Choosing a Database
      The next step in building your membership site is to decide which database to use. The two databases that Site Server supports for Membership Servers are Microsoft Access and SQL Server.™ While Microsoft Access databases are great for prototyping and are the easiest to set up, they are of limited use in a production environment. Any serious development effort should use SQL Server for speed and scalability. For an overview of the differences between Microsoft Access and SQL Server, see Figure 2.
      However, since there is no overhead in creating a Membership Server to use Microsoft Access and the site I'm building is just an example, I'll use Microsoft Access for my Membership Server. Here are some tips for those of you who wish to use SQL Server.

  • Make sure you have enough RAM; SQL Server is a RAM- intensive application.
  • Make sure that you use both TCP/IP and named pipes for your network protocols, and that all clients from ODBC sources come via TCP/IP.
  • When initially creating the membership database devices, set aside 20MB for the database and 5MB for the logs.

      Although using Microsoft Access for your Membership Server database is simple and quick to set up, keep in mind that the size of the Microsoft Access database directly correlates to the speed of the requests. When moving to a production environment, you should consider exporting or upsizing the Microsoft Access database to SQL Server to reap the performance benefits.

Creating the Membership Store and Mapping to IIS
      OK, you're all set. You know what a Membership Server is, and you've decided on the type of database to use. Now you'll use the wizard to create a new membership instance and map this instance to a Web server.
      Although all of the actions performed to create a Membership Directory support automation or scripting, it's easier to use the wizards. To get to the wizard, you need to open the MMC and expand the Personalization & Membership snap-in. After it expands, right-click on the computer icon with your machine name and select New | Membership Server Instance (see Figure 3).

Figure 3: Creating a Membership Server
Figure 3: Creating a Membership Server

      Now, with the New Membership Wizard open, press Next and select Custom Configuration. From this screen, select only AUO and the LDAP Service options. These options will allow you to access the Membership Directory from the Active User Object (AUO) and via LDAP. Don't select the Message Builder Service because you won't be using any mailing features here. Again, press the Next button, and create a new membership directory.
      After navigating to the next screen in the wizard, you will be prompted to select an authentication mode. Remember the two security configurations I discussed earlier? This is where you make the decision to use the existing Windows NT user base or a membership user base. I'll select the membership authentication option since I don't want to create a Windows NT account for each member of my site.
      On the next screen you are asked to provide both a name and a password for the Membership Server instance. The name will be used as the realm when authenticating, and is the root node of the Membership Directory. The password is used for the administrator account (which is separate from the Windows NT administrator account) to administer the Membership Server. For this demo, use the name "Web Members" and set the password to "password."
      Pressing the Next button will display a screen prompting a database type. Select Microsoft Access and accept the defaults for all of the other options in the wizard.
      When the wizard has completed, a screen will display the name of the proxy user on your local Windows NT-based machine. Write this user name down, as it is dynamically granted rights to the system based on the assigned rights of the membership user.
      Before you move on, right-click on the new Membership Server, which will be listed as Membership Server #n (n = number of existing Membership Servers plus 1) and rename it "Web Members."
      Before you can authenticate users from the Web as members, you need to map the Web Members Membership Server to a Web server instance. Create a new directory under InetPub named Demo and create a new virtual server instance on an unused port. I usually use port 5000 and point it to the new Demo directory.
      Next, you need to map your Membership Server to the Demo Web server instance. This can all be accomplished from the MMC by simply right-clicking on the Web server instance, selecting Task | Membership server mapping, and selecting Web Members from the list of membership stores available in the dropdown menu.
      As soon as you click OK, press F5 and look for the new Web application (or virtual directory) _mem_ bin, which will contain two subfolders named Images and Trouble. This Web application contains all the files necessary to support the Membership Server mapping to the Membership Directory. Along with these files are special error and logon pages, as well as several ASP troubleshooting wizards.
      Creating and mapping a Membership Server instance to a Web server is very simple once you familiarize yourself with the MMC. All the tools you need to administer and configure the Membership Server are provided through wizards.

User Authentication and Personalization
      Once a Web site has been marked as using Personalization & Membership, users are authenticated as they navigate within the site. The authentication methods used are cookies, HTML forms, basic/Clear Text authentication, and Distributed Password Authentication (DPA). In addition to providing various levels of security, each method allows for anonymous authentication. A site can use one of these methods or can choose different authentication types, depending on the level of security or membership the site requires. You can try these different authentication types by creating or copying any HTML or ASP page to the InetPub\Demo folder.
      In the MMC, right-click on the Web instance and select Properties | Membership authentication. Make sure anonymous is not checked and that Basic/Clear Text Authentication is selected. Navigate to http://localhost:5000/ and, when prompted for a username and password, enter "Administrator" and the password that you selected when you set up the Membership Server (password).
      As discussed earlier, user and group permissions provide more granular access with either a Windows NT public group that is assigned ACLs and ACEs dynamically or by using existing Windows NT users. This is accomplished by adding the membership proxy user or group that was created by the wizard to the entire file system that you want your members to access. Since the user is also a Windows NT user, all you're really doing is granting the membership users or groups access rights on the file system dynamically.
      Anonymous authentication is the only authentication method that can work alongside the other methods. Although it cannot be used by itself, anonymous users can personalize their experience and save properties and settings for the duration of their session, or until they delete their cookie. In addition, if the site allows anonymous users to be promoted between security levels, the user will not lose any settings during the promotion from anonymous to member.
      The most common authentication to use in addition to anonymous authentication is through cookies. Cookie authentication identifies the user with a cookie stored on the user's local machine. The cookie only stores a GUID and user name. These values correspond to the GUID and CN of the user as stored in the Membership Server. During a session, any personal information can remain on the server, referenced by a GUID.
      Cookies are not the solution for everyone, however. They can easily be erased from the client machine, and some users object to them. That's why there are several other supported methods of authentication. Forms authentication uses HTML forms to provide the user with a common interface that can be customized based on the requirements of the site. For example, you can redesign the provided forms in the _mem_bin virtual folder to use your site's graphics, logos, and typefaces.
      In addition to forms authentication, both DPA and Basic/Clear Text provide the user with an authentication box to enter a user name and password. DPA is only supported by Microsoft Internet Explorer 4.0 and later, while Basic/Clear Text is support by nearly every browser.
      Choosing the appropriate authentication method for your site is important. Maybe you don't want your users to have to log in every time, but you still want to personalize content if you recognize them (via a cookie). Sometimes it becomes necessary to ask for a user name and password, especially when the data is meant to be private. I recommend that you support multiple methods of authentication on your site. Provide cookie authentication on everything but critical data, which you can then authenticate with one of the other methods, along with Secure Sockets Layer (if necessary) to provide an encrypted logon.

The Active User Object
      Now that you have the Membership Server ready, where do you get members? Good question. You can either add them via the MMC with its wizards, or you can add them programmatically. To write the code that adds and modifies users, you need a special object that knows how to talk to the Membership Server. This special object is the Active User Object.
      The AUO is a server-side COM object that is registered and added to your system when you install Site Server 3.0. When the AUO object is activated, it checks which IIS virtual server it's running on, then checks which Personalization & Membership Server that the IIS server is mapped to. It then retrieves the AUO configuration and determines which Membership Directory to use. From there, the AUO determines who the user is based on the membership authentication method that the site employs.
      Using the AUO object to manipulate the Membership Directory and retrieve user information is as simple as declaring:


 <%
 Dim AUOUser
 Set AUOUser = Server.CreateObject("Membership.UserObjects.1")
 %>
This statement creates the AUOUser object and maps to the current user's profile or to an anonymous profile (if enabled).
      Once the AUO object has been created, it is easy to retrieve any relevant information you want. For example, to get the current user's CN, dimension a new variable and assign the value of either

 <%
 Dim strUserCn
 strUserCn = AUOUser.cn
 %>
or

 <%strUserCn = AUOUser.get cn
 Response.Write ("Your user name is: " & strUserCn)
 %>
Either way will work equally well, although I prefer the more direct AUOUser.cn method.
      To add information to the Membership Directory—assuming that the particular attribute exists—simply call the Put method for any number of items to be added, followed by the SetInfo method. Once an attribute has been added to the Membership Directory through a script or program, you can't set its value to null; you must remove it with the PutEX method. For example, after a user completes a form and posts the information back to the ASP, you should check for any nulls that the user may have sent and handle them accordingly (see Figure 4).
       Figure 5 lists some of the more commonly used AUO methods. If you want to see all of the methods and properties of the AUO object, you can use everyone's old friend, OLEView. AUO is listed under the ProgID of the Membership.UserObjects collection.
      Using the AUO object to retrieve and set user information is simple and straightforward. The set of APIs for the AUO hides from the developer the complexity of using the object to manipulate the Membership Directory. How does the AUO know who the user is? Just remember: the first thing that always happens on a personalization and membership-enabled site is authentication.

Putting It All Together
      You can now implement a simple personalization and membership-capable ASP. The code within the ASP can perform three tasks: create a user, update a profile, and remember the user when they've lost their cookies.
      First, create a new file named UserProfile.asp in the Demo directory that you already created, and paste in the code from Figure 6. Next create another file in the same directory named libDSUtils.inc and paste in the code from Figure 7.
      Third, open the MMC and right-click on UserProfile.asp. Select Properties and change the membership authentication type to support anonymous and cookie authentication. Do the same for libDSUtils.inc. This way, when the page is accessed for the first time, any user can access it. This is necessary since this page will also migrate the anonymous account to a member account by using the MoveHere method of the AUO.
      When a user accesses the page for the first time, a cookie is sent to their machine. And since you have anonymous cookie authentication turned on, this cookie identifies the user as an anonymous user. If you read through the code, you will notice that you never send an anonymous user any cookies. This is handled automatically when a user first accesses the site.
      The anonymous user can't do much more than complete a form to request a membership account. After choosing a user name and password and pressing Submit, the user name (CN) and password (userPassword) attributes are posted back to the ASP. The page detects if a post has been performed by checking whether or not the Request.Form("submit") variable contains data.
      If Request.Form("submit") contains data, a new user is created in the Membership Directory with the CN value set to the user name and the userPassword value set to the password. However, something more discreet is happening behind the scenes. The GUID that identifies the user has remained the same. This is possible because the user was never really created. Rather, the anonymous account was promoted to a membership account and given a CN and userPassword.
      Once the user has been moved, send a new cookie that will identify the user as a member, rather than as an anonymous user. This way, users can close the browser, open it up again, go to the same UserProfile.asp page, and have the page remember them.
      The user now have the opportunity to add some information. After the user fills in both a first name and last name, you can post the information back to the page to be processed and updated.
      However, what happens when your user wants to log in from another machine or loses the cookie that identifies him or her? Simply ask the user to log in again and look for a match in the Membership Directory for that user. If the users name and password match, send that user a new cookie built from their existing information. To see this in action, create a new user, fill out some information, close your browser, and toss your cookies. Next, open up the UserProfile.asp page and enter your user name and password. Your user information magically reappears. Voilą—a roaming user profile.
      The main functions that you use are included in the libDSUtils.inc file, which you can #include into your own ASP applications. The three functions are:

  • GetDSRootPath, which returns the root path of the Membership Directory
  • GetLdapServerAndPort, which returns the LDAP server name and port number
  • SendCookiesToNewUser, which builds a cookie for the user from their existing information
      If you encounter any errors with the pages, close your Web browser and delete any cookies that pertain to your machine. If you do the development and testing on one machine, it is common to have identifying cookies for one Membership Server that are incorrect for the server you're trying to access.

Conclusion
      Due to the proliferation of information available on the Web, users find it increasingly difficult to find the information they want. Yet at the same time, users expect sites to be more responsive to their needs. The Site Server personalization and membership functionality fulfills this need by allowing site developers to access usage patterns, build user profiles, and combine this information to give users an intuitive information resource.
      Site Server personalization and membership is a complex but fascinating tool, and I hope this article helps you implement it in your own project.

From the August 1998 issue of Microsoft Interactive Developer.