Return to ASPNET2SecurityHowTos


How To: Use the Membership Feature in ASP.NET 2.0

J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley
Microsoft Corporation
May 2005

Applies to

ASP.NET 2.0

Summary

This How To explains how you can use two different membership providers: the ActiveDirectoryMembershipProvider and the SqlMembershipProvider. The membership feature greatly reduces the amount of code you have to write to authenticate users at your Web site. The ActiveDirectoryMembership provider uses Active Directory to maintain user information, while the SqlMembershipProvider stores user details in a SQL Server database.

Contents

* Overview
* Using ActiveDirectoryMembershipProvider
* Using SQLMemberShipProvider
* ActiveDirectoryMembershipProvider Configuration Attributes
* SqlMembershipProvider Configuration Attributes
* Membership APIs

Overview

The new membership features of ASP.NET version 2.0 provide secure credential storage for application users and a Membership API that greatly simplifies the task of validating user credentials when used with Forms authentication. Membership providers abstract the underlying store used to maintain user credentials. ASP.NET 2.0 includes the following providers:
* ActiveDirectoryMembershipProvider This uses either an Active Directory (AD) or Active Directory Application Mode (ADAM) user store.
* SqlMembershipProvider This uses a SQL Server user store.

Note: Because ADAM is not a popular user principal store, this How To focuses on the AD store only.

The pluggable membership architecture allows you to add support for your own user stores; for example, other Lightweight Directory Access Protocol (LDAP) directories or other existing corporate identity stores. To do so, you create a custom provider that uses the MembershipProvider abstract class.
Typically, the user store contains user credentials such as user name and password, and in some cases, personalization information.
Take care not to mix personalization with authentication. If you only need to identify users for personalization reasons, a simple user name inside a cookie is sufficient. Authenticated access and Forms authentication is required if you want to restrict and control access to different areas and functions of your Web site and if you need to audit operations attributed to different users.

Using ActiveDirectoryMembershipProvider

You use the ActiveDirectoryMembershipProvider with Forms authentication if your user information is stored in Active Directory. Typically, this situation occurs when you have an intranet application that needs to accommodate mixed browser types, where using integrated Windows authentication is not possible.

Summary of Steps

The following steps explain how to use the ActiveDirectoryMembershipProvider.
* Step 1: Configure Forms authentication.
* Step 2: Configure ActiveDirectoryMembershipProvider.
* Step 3: Create users.
* Step 4: Authenticate users.

Step 1: Configure Forms Authentication

Set the <authentication> element's mode attribute to "Forms" and configure your application's Web.config file as shown in the following example.

		 <authentication mode="Forms">
		    <forms loginUrl="Login.aspx"    
		           protection="All"                     
		           timeout="30"                         
		           name="AppNameCookie"                                 
		           path="/FormsAuth"                      
		           requireSSL="true"                    
		           slidingExpiration="true"             
		           defaultUrl="default.aspx"
		           cookieless="UseCookies"
		           enableCrossAppRedirects="false"/>
		 </authentication>
	

Where:
* loginUrl points to the login page. Ideally, you should place this in a folder that requires Secure Socket Layer (SSL) for access.
* protection is set to "All" to specify privacy and integrity for the Forms authentication ticket.
* timeout is used to specify a limited session lifetime.
* name and path are set to unique values for the current application.
* requireSSL is set to "true" to specify that the authentication cookie should only be transmitted over an SSL-protected channel.
* slidingExpiration is set to "true" to enforce a sliding session lifetime. This means that the timeout is reset after each request to your application.
* defaultUrl is set to the Default.aspx page for the application.
* cookieless is set to "UseCookies" to specify that the application uses cookies to send the authentication ticket to the client.
* enableCrossAppRedirects is set to "false" to indicate that the application cannot redirect requests outside the application scope.

Add the following <authorization> element beneath the <authentication> element. This permits only authenticated users to access the application. The previously established loginUrl attribute of the <authentication> element will redirect unauthenticated requests to the Login.aspx page.

		 <authorization> 
		   <deny users="?" />
		   <allow users="*" />
		 </authorization>
	

Step 2: Configure ActiveDirectoryMembershipProvider

Configure the ActiveDirectoryMembershipProvider in your application's Web.config file as shown in the following example.

		 <connectionStrings>
		  <add name="ADConnectionString" 
		   connectionString=
		    "LDAP://domain.testing.com/CN=Users,DC=domain,DC=testing,DC=com" />
		 </connectionStrings>
	

		 <system.web>
		 ...
		 <membership defaultProvider="MembershipADProvider">
		  <providers>
		    <add
		      name="MembershipADProvider"
		      type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral,  PublicKeyToken=b03f5f7f11d50a3a"
		                connectionStringName="ADConnectionString"                                
		                connectionUsername="<domainName>\administrator" 
		                connectionPassword="password"/>
		   </providers>
		 </membership>
		 ...
		 </system.web>
	


Note: Make sure to set the defaultProvider attribute value to your ActiveDirectoryMembershipProvider. You need to do this to override the machine-level default which uses the SQLMembershipProvider that uses the local SqlExpress instance.

In addition to the above attributes, the ActiveDirectoryMembershipProvider has additional attributes that you can optionally overwrite. For more information, see the section, "ActiveDirectoryMembershipProvider Configuration Attributes," in this document.

Step 3: Create Users

You can create new users in the following ways:
* Use the Web Site Administration Tool, which provides a wizard-like interface for creating new users.
* Create an ASP.NET page that contains a CreateUserWizard control to create a new user. This control uses the configured membership provider to encapsulate the logic of creating a new user.
* Create an ASP.NET Web page that contains TextBox controls to obtain the user name and password (and optionally an e-mail address), and then use the CreateUser Membership API method to programmatically create the new user.


Note: All of these techniques use the Membership.CreateUser method.

The default configuration for the ActiveDirectoryMembershipProvider uses User Principal Names (UPNs) for name mapping, as shown below:

		 attributeMapUsername="userPrincipalName"
	

Therefore all user names must have the following format:

		 [UserName@DomainName]
	

If you call Membership.CreateUser programmatically, use this format:

		 Membership.CreateUser("UseName@DomainName",
		                      "Secret",
		                      "userName@emailAddress"); 
	

You can change the user mapping type by setting the following attribute in the Membership Provider configuration in the Web.config file.

		 attributeMapUsername="sAMAccountName"
	

With this configuration, supply user names in the following format:

		 [UserName]
	

For example:

		 Membership.CreateUser("UserName", 
		                      "Secret", 
		                      "userName@emailAddress")
	


Note: You should set the requiresUniqueEmail attribute to "true" to ensure that users supply unique e-mail addresses

Step 4: Authenticate Users

To authenticate users, you must provide a login form. This could be a separate page or a special area on your application's home page.
There are two ways to do this:
* You can use the new ASP.NET 2.0 login controls.
The ASP.NET login controls encapsulate nearly all of the logic required to obtain credentials from users and to validate them against a user store. They use the configured membership provider. You do not need to write any additional code.
After the user is validated, the login controls automatically save information about the user — for example, by using an encrypted cookie if the user's browser accepts cookies.
* You can create custom login forms by using ASP.NET TextBox controls.
If you have created a custom login form with simple TextBox controls, you can prompt the user for a user name and password, and then call the ValidateUser method of the Membership class to perform the validation.
You also need to call methods of the FormsAuthentication class to create the cookie and write it to the user's computer as shown below.
		 if [(Membership.ValidateUser(userName.Text,] password.Text))
		 {
		  if (Request.QueryString["ReturnUrl"] != null)
		  {
		    [FormsAuthentication.RedirectFromLoginPage(userName.Text,] false);
		  }
		  else
		  {
		    [FormsAuthentication.SetAuthCookie(userName.Text,] false);
		  }
		 }
		 else
		 {
		  Response.Write("Invalid UserID and Password");
		 }
	

Note: Both of these techniques use the Membership.CreateUser method.

The default ActiveDirectoryMembershipProvider configuration uses user principal names (UPNs) for name mapping. If you call the Membership.ValidateUser method, be sure to use a UPN name as shown here:

		 bool [isValidUser] = [Membership.ValidateUser(]
		                                  "UseName@DomainName", 
		                                  "Secret"); 
	

You can change the mapping for user by setting following attribute in Membership Provider configuration in Web.config file.

		 attributeMapUsername="sAMAccountName"
	

With this configuration, you must call Membership.ValidateUser as shown here:

		 bool [isValidUser] = Membership.ValidateUser("UserName", 
		                                           "Secret", 
		                                           "userName@emailAddress")
	

Using SQLMemberShipProvider

You use the SQLMembershipProvider with Forms authentication if your user information is stored in SQL Server. Typically, this occurs when you have an intranet where user information is application-specific or where the application is Internet facing and the users do not have Active Directory accounts.
When you install ASP.NET, the Machine.config file for your server includes configuration elements that specify SQL Server providers for Membership. By default, the SQL provider is configured to connect to the local instance of SQL Server.

Summary of Steps

The following steps explain how to use the SQLMembershipProvider.
* Step 1: Configure Forms authentication.
* Step 2: Set up the database for SqlMembershipProvider.
* Step 3: Configure SqlMembershipProvider.
* Step 4: Create users.
* Step 5: Authenticate users.

Step 1: Configure Forms Authentication

Set the <Authentication> element mode attribute to "Forms" and then configure it in your application's Web.config file, as shown here:

		 <authentication mode="Forms">
		   <forms loginUrl="Login.aspx"    
		          protection="All"                     
		          timeout="30"                         
		          name="AppNameCookie"                                 
		          path="/FormsAuth"                      
		          requireSSL="true"                    
		          slidingExpiration="true"             
		          defaultUrl="default.aspx"
		          cookieless="UseCookies"
		          enableCrossAppRedirects="false" />
		 </authentication>
	

Where:
* loginUrl points to the login page. Ideally, you should place this in a folder that requires Secure Socket Layer (SSL) for access.
* protection is set to "All" to specify privacy and integrity for the Forms authentication ticket.
* timeout is used to specify a limited session lifetime.
* name and path are set to unique values for the current application.
* requireSSL is set to "true" to specify that the authentication cookie should only be sent only over an SSL-protected channel.
* slidingExpiration is set to "true" to enforce a sliding session lifetime. This means that the timeout is reset after each request to your application.
* defaultUrl is set to the Default.aspx page for the application.
* cookieless is set to "UseCookies" to specify that the application uses cookies to send the authentication ticket to the client.
* enableCrossAppRedirects is set to "false", to indicate that the application cannot redirect the request outside the application scope.

Add the following <authorization> element beneath the <authentication> element. This permits only authenticated users to access the application. The previously established loginUrl attribute of the <authentication> element redirects unauthenticated requests to the Login.aspx page.

		 <authorization> 
		   <deny users="?" />
		   <allow users="*" />
		 </authorization>
	

Step 2: Set up the Database for SqlMembershipProvider

Before you can use the SqlMembershipProvider, you must install the SQL Server membership database.
To install the membership database, log on to your server with an account that has authority to administrate SQL Server (such as the Administrator account). Open the Visual Studio 2005 command prompt, and run the following command:

		 aspnet_regsql.exe -E -S localhost -A m
	

Where:
* -E indicates authenticate using the Windows credentials of the currently logged on user.
* -S <server> indicates the name of the server where the database will be installed or is already installed.
* -A m indicates add membership support. This creates the relevant tables and stored procedures required by the membership provider.


Note: The Aspnetregsql tool is also used to install database elements for other ASP.NET 2.0 features, such as Role Management, Profile, Web Parts Personalization, and Web Events. Other command-line arguments perform database operations for these other features. You can use Aspnetregsql without any command line arguments by using a wizard that allows you to specify connection information for your SQL Server and install or remove the database elements for all of the supported features.

Step 3: Configure SqlMembershipProvider

The Machine.config file contains a default SqlMembershipProvider instance (AspNetSqlProvider) that connects to the SQL Server instance (SQLExpress) on the local computer. You can use this instance of the provider if you are running SQL Server locally. Alternatively, you can specify provider details in your application's Web.config, as shown here:

		 <connectionStrings>
		  <add name="MySqlConnection" connectionString="Data [Source=MySqlServer;Initial] Catalog=aspnetdb;Integrated  Security=SSPI;" />
		 </connectionStrings>
		 <system.web>
	
...
		  <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
		    <providers>
		      <clear />
		      <add 
		        name="SqlProvider" 
		        type="System.Web.Security.SqlMembershipProvider" 
		        connectionStringName="MySqlConnection"
		        applicationName="MyApplication"
		        enablePasswordRetrieval="false"
		        enablePasswordReset="true"
		        requiresQuestionAndAnswer="true"
		        requiresUniqueEmail="true"
		        passwordFormat="Hashed" />
		    </providers>
		  </membership>
	

Make sure to set the defaultProvider attribute value to point to your provider definition. The default value points to AspNetSqlProvider, which uses the local SqlExpress instance.
For more information, refer to the section, “SqlProviderMembershipProvider Configuration Attributes,” in this document.

Step 4: Create Users with SqlMembershipProvider

You can create new users in the following ways:
* Use the Web Site Administration Tool, which provides a wizard-like interface for creating new users.
* Create an ASP.NET page that contains a CreateUserWizard control to create a new user. This control uses the configured membership provider to encapsulate the logic of creating a new user.
* Create an ASP.NET Web page that contains the TextBox controls used to collect user name and password details (and optionally an e-mail address), and then use the Membership.CreateUser API to create a new user in the membership system.

The following code shows how to call Membership.CreateUser.

		 Membership.CreateUser("UseName", "Secret", "userName@emailAddress"); 
	

Step 5: Authenticate Users

To authenticate users, you must provide a login form. This could be a separate page or a special area on your application's home page.
There are two ways to do this:
* You can use the new ASP.NET 2.0 login controls.
The ASP.NET login controls encapsulate nearly all of the logic required to obtain credentials from users and to validate them against a user store. They use the configured Membership provider. You do not need to write any additional code.
After the user is validated, the login controls automatically save information about the user — for example, by using an encrypted cookie if the user's browser accepts cookies.
* You can create custom login forms by using ASP.NET TextBox controls.
If you have created a custom login form with simple TextBox controls, you can prompt the user for a user name and password, and then call the ValidateUser method of the Membership class to perform the validation.
You need to call methods of the FormsAuthentication class to create the cookie and write it to the user's computer.

ActiveDirectoryMembershipProvider Configuration Attributes

Table 1 lists the ActiveDirectoryMembershipProvider configuration attributes, their default values, and notes for their usage.

Table 1. ActiveDirectoryMembershipProvider Configuration Attributes

Attribute Default Value Notes
connectionStringName Points to a connection string contained in the connection strings configuration section. This attribute is required because it points to the primary LDAP bind string that is used for create, update, get, and validate operations.
connectionUserName Defines the user name used for authentication purposes when connecting to the directory. If this attribute is specified, the companion password attribute must also be specified. This attribute is used to configure a set of credentials that can be used to connect to the directory instead of using the process account or impersonation credentials that are in effect at the time the provider connects to the directory.
connectionPassword Defines the password used for authentication purposes when connecting to the directory. If this attribute is specified, the companion username attribute must also be specified. This attribute is used to configure a set of credentials that can be used to connect to the directory instead of using the process account or impersonation credentials that are in effect at the time the provider connects to the directory
connectionProtection Secure Defines the transport layer security options that are used when opening connections to the directory. This attribute can have one of the following string values: “Secure” or “None”. If set to “Secure”, the provider attempts to select the highest level of connection security available based on the type of directory that the provider connects to. The protection is determined as follows: SSL is first attempted because SSL is an option that works both with AD and with ADAM (ActiveDirectoryConnectionProtection.Ssl). If SSL is not available and the provider is connecting to either AD or to a domain-joined ADAM instance, encrypt-sign-and-seal is used (ActiveDirectoryConnectionProtection.SignAndSeal). If neither SSL nor encrypt-sign-seal is available, the provider throws a ProviderException stating that it could not automatically select a secure connection to the configured directory.
enablePasswordReset False Controls whether or not a password can be reset. For security reasons, with the ActiveDirectoryMembershipProvider, this attribute can only be set to true if all of the following have been set: requiresQuestionAndAnswer is set to true passwordQuestion, passwordAnswer, attributeMapFailedPasswordAnswerCount attributeMapFailedPasswordAnswerTime, and attributeMapFailedPasswordAnswerLockoutTime have been mapped to attributes in the directory. Note - Even if this attribute is set to true, password resets are allowed only if the credentials used to perform the reset have Administrator privileges in AD.
enableSearchMethods False Allows an administrator to set whether or not search-oriented methods can be called on the provider instance. Because methods such as Find* and GetAllUsers are potentially very expensive, the default value for this attribute is false. The following methods throw a NotSupportedException if they are called when this attribute is set to false: FindUsersByName FindUsersByEmail GetAllUsers
requiresQuestionAndAnswer False Determines whether a password question and answer are required when performing a password reset. For security reasons, with ActiveDirectoryMembershipProvider, this attribute can only be set to true if all of the following have been set: attributeMapPasswordQuestion, attributeMapPasswordAnswer, attributeMapFailedPasswordAnswerCount, attributeMapFailedPasswordAnswerTime, and attributeMapFailedPasswordAnswerLockoutTime
applicationName / For this provider, applicationName is included for completeness with other providers. Internally, it does not matter what value is placed here because the application name is not used. The maximum value is 256 characters.
requiresUniqueEmail False Specifies whether the e-mail values used in the application must be unique.
maxInvalidPasswordAttempts 5 Indicates the number of failed password attempts or failed password answer attempts allowed before a user's account is locked. When the number of failed attempts equals the value set in this attribute, the user’s account is locked out. For the AD provider, this attribute applies only to managing resets that use a password answer. AD manages bad password attempts internally.
passwordAttemptWindow 10 Indicates the time window, in minutes, during which failed password attempts and failed password answer attempts are tracked. For the AD provider, this attribute applies only to managing resets that use a password answer. AD manages bad password attempts internally.
passwordAnswerAttemptLockoutDuration 30 Specifies the duration, in minutes, that a lockout due to a bad password answer is considered still in effect. Because AD uses the concept of timing out bad password lockouts, this attribute is necessary to support a similar concept of timing bad password answer attempts.
minRequiredPasswordLength 7 Specifies the minimum number of characters required in a password. The value can be from 1 to 128.
minRequiredNonAlphanumericCharacters 1 Specifies the minimum number of non-alphanumeric characters required in a password. This configuration attribute cannot be set to a value greater than the value of the minRequiredPasswordLength. This means the configuration setting must be in the range of 0…minRequiredPasswordLength, inclusive of minRequiredPasswordLength.
passwordStrengthRegularExpression "" Provides a valid regular expression that the provider will use as part of password strength validation.
attributeMapUsername userPrincipalName Defines the mapping from a property on a MembershipUser object to an attribute within the directory. The only allowed directory attributes for mapping to username when using AD are userPrincipalName or sAMAccountName. The only allowed directory attributes for mapping to username when using ADAM is userPrincipalName.
attributeMapEmail mail Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
attributeMapPasswordQuestion UNDEFINED Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
attributeMapPasswordAnswer UNDEFINED Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
attributeMapFailedPasswordAnswerCountUNDEFINED Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
attributeMapFailedPasswordAnswerTimeUNDEFINED Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
attributeMapFailedPasswordAnswerLockoutTime UNDEFINED Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
1. When the requiresQuestionAndAnswer attribute is set to "true", the ActiveDirectoryMembershipProvider class supports password reset security by requiring the user to answer a predetermined question.
To support the question and answer, you must set the attributeMapPasswordQuestion and attributeMapPasswordAnswer attributes when you use the <add> element to add the ActiveDirectoryMembershipProvider object beneath the membership <providers> element.

SqlMembershipProvider Configuration Attributes

Table 2 lists the SqlMembershipProvider configuration attributes, their default values, and notes for their usage.

Table 2. SqlMembershipProvider Configuration Attributes

Attribute Default Value Notes
connectionStringName Points to a connection string contained in the connection strings configuration section. This attribute is required because it points to the SQL connection string used for connecting to the SQL server database instance.
enablePasswordReset false Controls whether or not a password can be reset.For security reasons, with the SqlMembershipProvider, this attribute can only be set to true if all of the following have been set: requiresQuestionAndAnswer set to true passwordQuestion passwordAnswer
requiresQuestionAndAnswer false Determines whether a password question and answer are required when performing a password reset.
applicationName / Used to group user information. By qualifying user information with an application name, you can store information for multiple applications in a single database without running into conflicts between duplicate user names. Also, multiple ASP.NET applications can use the same user database by specifying the same value in the applicationName attribute. The maximum value allowed is 256 characters.
requiresUniqueEmail False Specifies whether the e-mail values used in the application must be unique.
maxInvalidPasswordAttempts 5 Indicates the number of failed password attempts or failed password answer attempts allowed before a user's account is locked. When the number of failed attempts equals the value set in this attribute, the user’s account is locked out.
passwordAttemptWindow 10 Indicates the time window, in minutes, during which failed password attempts and failed password answer attempts are tracked.
passwordFormat Hashed Specifies the password format. The SQL Server membership provider supports Clear, Encrypted, and Hashed password formats. Clear passwords are stored in plain text, which improves the performance of password storage and retrieval but is less secure because passwords are easily read if your SQL Server database is compromised. Encrypted passwords are encrypted when stored and can be decrypted for password comparison or password retrieval. This requires additional processing for password storage and retrieval, but is more secure because passwords are not easily deciphered if the SQL Server database is compromised. Hashed passwords are hashed using a one-way hash algorithm and a randomly generated salt value when stored in the database. When a password is validated, it is hashed with the salt value in the database for verification. Hashed passwords cannot be retrieved.
passwordAnswerAttemptLockoutDuration 30 Specifies the duration, in minutes, that a lockout due to a bad password answer is considered still in effect.
minRequiredPasswordLength 7 Specifies the minimum number of characters required in a password. The value can be from 1 to 128.
minRequiredNonAlphanumericCharacters 1 Specifies the minimum number of non-alphanumeric characters required in a password. This configuration attribute cannot be set to a value greater than the value of the minRequiredPasswordLength. This means the configuration setting must be in the range of 0…minRequiredPasswordLength, inclusive of minRequiredPasswordLength.
passwordStrengthRegularExpression "" Provides a valid regular expression that the provider will use as part of password strength validation.

Membership APIs

Table 3 lists some of the more important methods of the Membership class, along with their parameters and usage notes.

Table 3. Membership Class Methods

Method Parameters Notes
CreateUser string username – Username to create. string password – Password for new user. string email – Email for new user. String passwordQuestion. String passwordAnswer. Bool IsApproved. object providerUserKey Used to create a new user.
DeleteUser string username – User to delete. bool removeAllRelatedData Used to immediately remove a user identified by the supplied username. Returns true if the user was deleted, and false if not found.
FindUsersByName string usernameToMatch. int pageIndex. int pageSize. Returns a collection of users where the string parameter passed matches part of the username. Wildcard support idepends on how each data store handles characters such as “*”, “%” and “_”.
FindUsersByEmail string emailToMatch. int pageIndex. int pageSize Returns a collection of users where the string parameter passed matches any part of the e-mail. Wildcard support idepends on how each data store handles characters such as “*”, “%” and “_”
GeneratePassword None A helper method used in automatically generating strong passwords for password reset functionality. Internally it simply calls Membership.GeneratePassword(14).
GetAllUsers int pageIndex. int pageSize Returns a subset of users from the collection of all users. The subset is based on the pageIndex and pageSize methods.
GetNumberOfUsersOnline None Returns a count of all the users currently online. The AD provider does not implement this functionality
GetUserNameByEmail string email – Email of user to lookup. Return a member’s username.
UpdateUser MembershipUser user – Membership user to update Updates a member’s properties, for example, an e-mail address.
ValidateUser string username – User name to validate. string password – User password to validate. Validates a user’s credentials. Returns true if the credentials are valid and false if they are not. With AD, regardless of the configured connection credentials, the provider connects to the directory with the username and password parameter as the connection credentials.

Note: The GetAllUsers method will be removed in the RTM version of .NET Framework 2.0.



Return to ASPNET2SecurityHowTos
Microsoft Communities