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 Aspnet
regsql 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. |
| attributeMapFailedPasswordAnswerCount | UNDEFINED | Defines the mapping from a property on a MembershipUser object to an attribute within the directory. |
| attributeMapFailedPasswordAnswerTime | UNDEFINED | 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