ASP.NET Membership enables you to create new users, delete users, and edit user properties. It's the framework that is used behind the scenes by the Login controls. ASP.NET Membership picks up where Forms authentication leaves off. Forms authentication provides you with a way of identifying users. ASP.NET Membership is responsible for representing the user information. ASP.NET Membership uses the provider model. The ASP.NET Framework includes two Membership providers:
In this section, you learn how to use the ASP.NET Membership application programming interface. You learn how to use the Membership class to modify membership information programmatically. You also learn how to configure both the SqlMembershipProvider and the ActiveDirectoryMembershipProvider. For example, you learn how to modify the requirements for a valid membership password. Finally, we build a custom Membership provider. It is an XmlMembershipProvider that stores membership information in an XML file. Using the Membership Application Programming InterfaceThe main application programming interface for ASP.NET Membership is the Membership class. This class supports the following methods:
This class also supports the following event:
You can use the methods of the Membership class to administer the users of your website. For example, the page in Listing 21.15 displays a list of every registered user (see Figure 21.5). Figure 21.5. Displaying registered users.Listing 21.15. ListUsers.aspx
In Listing 21.15, an ObjectDataSource control is used to represent the Membership class. The GetAllUsers() method is called to get the list of users. You also can use the methods of the Membership class to create custom Login controls. For example, notice that you can retrieve the number of users currently online by calling the GetNumberOfUsersOnline() method. The custom control in Listing 21.16 displays the value returned by this method. Note Chapter 31, "Building Custom Controls," discusses custom control building. Listing 21.16. UsersOnline.vb
The page in Listing 21.17 uses the UsersOnline control to display the number of users currently online (see Figure 21.6). Figure 21.6. Display number of users online.Listing 21.17. ShowUsersOnline.aspx
Note A user is considered online if his username was used in a call to the ValidateUser(), UpdateUser(), or GetUser() method in the last 15 minutes. You can modify the default time interval of 15 minutes by modifying the userIsOnlineTimeWindow attribute of the membership element in the web configuration file. Several of the methods of the Membership class return one or more MembershipUser objects. The MembershipUser object is used to represent a particular website member. This class supports the following properties:
Notice that the MembershipUser class does not contain a property for the user's password or password answer. This is intentional. If you need to change a user's password, then you need to call a method. The MembershipUser class supports the following methods:
Encrypting and Hashing User PasswordsBoth of the default Membership providers included in the ASP.NET Framework enable you to store user passwords in three ways:
You configure how passwords are stored by setting the passwordFormat attribute in the web configuration file. For example, the web configuration file in Listing 21.18 configures the SqlMembershipProvider to store passwords in plain text. Listing 21.18. Web.Config
The default value of the passwordFormat attribute is Hashed. By default, actual passwords are not stored anywhere. A hash value is generated for a password and the hash value is stored. Note A hash algorithm generates a unique value for each input. The distinctive thing about a hash algorithm is that it works in only one direction. You can easily generate a hash value from any value. However, you cannot easily determine the original value from a hash value. The advantage of storing hash values is that even if your website is compromised by a hacker, the hacker cannot steal anyone's passwords. The disadvantage of using hash values is that you also cannot retrieve user passwords. For example, you cannot use the PasswordRecovery control to email a user his original password. Instead of hashing passwords, you can encrypt the passwords. The disadvantage of encrypting passwords is that it is more processor intensive than hashing passwords. The advantage of encrypting passwords is that you can retrieve user passwords. The web configuration file in Listing 21.19 configures the SqlMembershipProvider to encrypt passwords. Notice that the web configuration file includes a machineKey element. You must supply an explicit decryptionKey when encrypting passwords. Note For more information on the machineKey element, see the "Using Forms Authentication Across Applications" section, earlier in this chapter. Listing 21.19. Web.Config
Warning Make sure that you change the value of the decryptionKey attribute before using the web configuration file in Listing 21.19. You can generate a new decryptionKey with the GenerateKeys.aspx page described in the "Using Forms Authentication Across Applications" section, earlier in this chapter. Modifying User Password RequirementsBy default, passwords are required to contain at least 7 characters and 1 non-alphanumeric character (a character that is not a letter or a number such as *,_, or !). You can set three Membership provider attributes that determine password policy:
The minRequiredNonAlphanumericCharacters attribute confuses everyone. Website users are not familiar with the requirement that they must enter a non-alphanumeric character. The web configuration file in Listing 21.20 illustrates how you can disable this requirement when using the SqlMembershipProvider. Listing 21.20. Web.Config
Locking Out Bad UsersBy default, if you enter a bad password more than five times within 10 minutes, your account is automatically locked out. In other words, it is disabled. Also, if you enter the wrong answer for the password answer more than five times in a 10-minute interval, your account is locked out. You get five attempts at your password and five attempts at your password answer. (These two things are tracked independently.) Two configuration settings control when an account gets locked out:
For example, the web configuration file in Listing 21.21 modifies the default settings to enable you to enter a maximum of three bad passwords or bad password answers in one hour. Listing 21.21. Web.Config
After a user has been locked out, you must call the MembershipUser.UnlockUser() method to re-enable the user account. The page in Listing 21.22 enables you to enter a username and remove a lock (see Figure 21.7). Figure 21.7. Removing a user lock.Listing 21.22. RemoveLock.aspx
Configuring the SQLMembershipProviderThe SqlMembershipProvider is the default Membership provider. Unless otherwise configured, it stores membership information in the local ASPNETDB.mdf Microsoft SQL Server Express database located in your application's App_Data folder. This database is created for you automatically the first time that you use Membership. If you want to store membership information in some other Microsoft SQL Server database, then you need to perform the following two tasks:
To complete the first task, you can use the aspnet_regiis command-line tool. This tool is located in the following folder: \WINDOWS\Microsoft.NET\Framework\v2.0.50727 Note If you open the SDK Command Prompt, then you don't need to navigate to the Microsoft.NET folder before using the aspnet_regsql tool. If you execute the aspnet_regsql tool without supplying any parameters, then the ASP.NET SQL Server Setup Wizard appears (see Figure 21.8). You can use this wizard to select a database and install the Membership objects automatically. Figure 21.8. Using the ASP.NET SQL Setup Wizard.If you prefer, rather than use the aspnet_reqsql tool, you can execute the following two SQL batch files to install Membership: \WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallCommon.sql \WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallMembership.sql If you don't want to install the .NET Framework on your database server, then you can execute these SQL batch files. After you have configured your database to support ASP.NET Membership, you must configure your application to connect to your database when using Membership. The web configuration file in Listing 21.23 connects to a database named MyDatabase located on a server named MyServer. Listing 21.23. Web.Config
In Listing 21.23, a new default Membership provider named MyMembershipProvider is configured. The new Membership provider uses a connection string name that has the value MyConnection. The MyConnection connection string is defined in the connectionStrings element near the top of the configuration file. This connection string represents a connection to a database named MyDatabase located on a server named MyServer. Configuring the ActiveDirectoryMembershipProviderThe other Membership provider included in the ASP.NET Framework is the ActiveDirectoryMembershipProvider. You can use this provider to store user information in Active Directory or ADAM (Active Directory Application Mode). ADAM is a lightweight version of Active Directory. You can download ADAM from the Microsoft website (www.microsoft.com/adam). ADAM is compatible with both Microsoft Windows Server 2003 and Microsoft Windows XP Professional (Service Pack 1). If you want to use ASP.NET Membership with ADAM, then you need to complete the following two steps:
The following sections examine each of these steps in turn. Configuring ADAMFirst, you need to set up a new instance of ADAM. After downloading and installing ADAM, follow these steps:
Figure 21.9. Creating a new ADAM instance.After you have completed the preceding steps, a new ADAM instance named WebUsersInstance is created. The next step is to configure an ADAM administrator account. Follow these steps: Warning If you are using Windows XP, and you don't have an SSL certificate installed, then you need to perform an additional configuration step. Otherwise, you'll receive an error when you attempt to reset a user password. By default, you are not allowed to perform password operations over a non-secured connection to an ADAM instance. You can disable this requirement by using the dsmgmt.exe tool included with ADAM. Open the ADAM Tools Command Prompt and type the following series of commands:
If you don't use an SSL connection, then passwords are transmitted in plain text. Don't do this in the case of a production application.
Figure 21.10. Using ADAM ADSI Edit.After you complete this series of steps, an ADAMAdministrator account is configured. You need to use this account when connecting to the ADAM instance from the ActiveDirectoryMembershipProvider. Configuring the ActiveDirectoryMembershipProviderThe next step is to configure your application to use the ActiveDirectoryMembership provider. You can use the web configuration file in Listing 21.24. Listing 21.24. Web.Config
The web configuration file in Listing 21.24 configures a new default Membership provider named MyMembershipProvider. This provider is an instance of the ActiveDirectoryMembershipProvider. Several of the attributes used with the ActiveDirectoryMembershipProvider require additional explanation. The connectionStringName attribute points to the connection string defined in the connectionStrings section. This connection string connects to a local ADAM instance that listens on port 389. Notice that the connectionProtection attribute is set to the value None. If you don't modify this attribute, then you are required to use an SSL connection. If you do use an SSL connection, you need to change the port used in the connection string (typically port 636). The connectionUsername and connectionPassword attributes use the ADAMAdministrator account that you configured in the previous section. When you don't use an SSL connection, you must provide both a connectionUsername and connectionPassword attribute. Finally, notice that the provider declaration includes an enableSearchMethods attribute. If you want to be able to configure users by using the Web Site Administration Tool, then you must include this attribute. The ActiveDirectoryMembershipProvider class supports several attributes specific to working with Active Directory:
After you finish these configuration steps, you can use the ActiveDirectoryMembershipProvider in precisely the same way that you can use the SqlMembershipProvider. When you use the Login control, users are validated against Active Directory. When you use the CreateUserWizard control, new users are created in Active Directory. Creating a Custom Membership ProviderBecause ASP.NET Membership uses the provider model, you can easily extend ASP.NET membership by creating a custom Membership provider. There are two main situations in which you might need to create a custom Membership provider. First, imagine that you have an existing ASP.NET 1.x or ASP classic application. You are currently storing membership information in your own custom set of database tables. Furthermore, your table schemas don't easily map to the table schemas used by the SqlMembershipProvider. In this situation, it makes sense to create a custom Membership provider that reflects your existing database schema. If you create a custom Membership provider, you can use your existing database tables with ASP.NET Membership. Second, imagine that you need to store membership information in a data store other than Microsoft SQL Server or Active Directory. For example, your organization might be committed to Oracle or DB2. In that case, you need to create a custom Membership provider to work with the custom data store. In this section, we create a simple custom Membership provider: an XmlMembershipProvider that stores membership information in an XML file. Unfortunately, the code for the XmlMembershipProvider is too long to place here. The code is included on the CD that accompanies this book in a file named XmlMembershipProvider.vb, located in the App_Code folder. The XmlMembershipProvider class inherits from the abstract MembershipProvider class. This class has over 25 properties and methods that you are required to implement. For example, you are required to implement the ValidateUser() method. The Login control calls this method when it validates a username and password. You also are required to implement the CreateUser() method. This method is called by the CreateUserWizard control when a new user is created. The web configuration file used to set up the XmlMembershipProvider is contained in Listing 21.25. Listing 21.25. Web.Config
Notice that the XmlMembershipProvider supports a number of attributes. For example, it supports a passwordFormat attribute that enables you to specify whether passwords are stored as hash values or as plain text. (It does not support encrypted passwords.) The XmlMembershipProvider stores membership information in an XML file named Membership.xml, located in the App_Data folder. If you want, you can add users to the file by hand. Alternatively, you can use the CreateUserWizard control or the Web Site Administration Tool to create new users. A sample of the Membership.xml file is contained in Listing 21.26. Listing 21.26. App_Data\Membership.xml
The sample code folder on the CD includes a Register.aspx, Login.aspx, and ChangePassword.aspx page. You can use these pages to try out different features of the XmlMembershipProvider. Warning Dynamic XPath queries are open to XPath Injection Attacks in the same way that dynamic SQL queries are open to SQL Injection Attacks. When writing the XmlMembershipProvider class, I avoided using methods such as the SelectSingleNode() method to avoid XPath Injection Attack issues, even though using this method would result in leaner and faster code. Sometimes, it is better to be safe than fast. |