New Security Features in ASP.NET 2.0

 

Stephen Walther
Microsoft Corporation

June 2004

Applies to:
   Microsoft ASP.NET 2.0
   Microsoft ASP.NET framework
   Microsoft SQL Server
   Microsoft Visual Studio .NET

Summary: ASP.NET 2.0 includes a number of new features to make securing your ASP.NET applications easier than before. See how you can use the new controls, tools, and APIs to control access to pages, and make it easier to store information about your users. (15 printed pages)

Contents

Security and the Provider Model
Using the Web Site Administration Tool to Configure Security
Using the Login Controls to Create Standard Security Pages
Working Directly with the Membership API
Conclusion

ASP.NET 2.0 builds on ASP.NET 1.x to enable you to more easily create and manage users, and to password-protect pages in a Web application. The new framework includes new features for working with authentication and authorization, which were designed to appeal to both Web site administrators and developers.

Web site administrators can take advantage of the new Web Site Administration Tool to create new users and roles, and to control access to pages in a Web application. The Web Site Administration Tool is a set of prewritten ASP.NET pages that can be used by individuals with no programming skills to configure a Web application.

Developers can take advantage of the new Login controls in order to quickly build security related pages in a Web application. For example, a developer can create a login page simply by dragging a Login control onto an .aspx page. By taking advantage of the Login controls, a developer can build a login page, a registration page, or a password recovery page without writing any code.

Finally, the ASP.NET 2.0 framework contains new security related features which will appeal to advanced developers. The new Membership API is a set of classes that contains methods for creating and retrieving information about application users. In addition, the new framework contains classes that make it easier to work with custom user roles.

Security and the Provider Model

The biggest change that you get with the ASP.NET 2.0 framework is that security just works. With the new framework, you can start registering and authenticating users against a database of users immediately after you enable Forms Authentication, without building any database tables or writing any code. This is possible because the ASP.NET 2.0 framework uses the Provider Model for security.

The Provider Model—which is used throughout the ASP.NET 2.0 framework—gives you a standard method for plugging in components, which implement different services for your application. The ASP.NET 2.0 framework uses two types of providers for security: the Membership Provider and the Role Provider. The Membership Provider is used to store usernames and passwords, and the Role Provider is used to store user roles.

The default Membership Provider is the AccessMembershipProvider. This provider stores usernames and passwords in a Microsoft Access database. The Access database is automatically created for you in your application's Data folder (If you accidentally delete the Access database, it is automatically recreated the next time you attempt to connect to the database). Whenever you create a new Web application, the Access Provider will automatically create everything you need to start authenticating users.

The ASP.NET 2.0 Framework ships with two Membership Providers: the default AccessMembershipProvider,and a SqlMembershipProvider. If you want to store membership information in a Microsoft SQL Server database, you can configure your application to use the SqlMembershipProvider without rewriting any of your application code (The steps for enabling the SqlMembershipProvider are discussed in the next section).

You can also create a custom Membership Provider. For example, you might want to store membership information in an XML file, a FoxPro database, or an Oracle database. You might even want to implement a Membership Provider that retrieves membership information through a Web service. If you want to create your own Membership Provider, you need to implement all of the methods and properties of the abstract MembershipProvider class (A Membership Provider is nothing more than an instance of the MembershipProvider base class).

Using the SqlMembershipProvider

Using an Access database is just fine while you are in the process of developing a Web application, or when you are developing an application that is intended to be used by a small number of people. If you need to build a more robust application, however, you'll want to store usernames and passwords in a more scalable database, such as Microsoft SQL Server.

If you want to store membership information in a Microsoft SQL Server database instead of the default Microsoft Access database, you need to modify the default Membership Provider for your application. The following application Web.Config file sets the AspNetSqlProvider as the default Membership provider:

<configuration>
    <system.web>
        <membership defaultProvider="AspNetSqlProvider" />
    </system.web>
</configuration

If you don't want to update your application's Web.Config file by hand, you can also switch providers by using either the Web Site Administration Tool (described in the next section) or the ASP.NET Microsoft Management Console (MMC) snap-in for Internet Information Services. Both of these tools provide you with a user-friendly interface for specifying the Membership provider.

Unlike the Microsoft Access Provider, before you can use the SQL Provider you must create the necessary database tables and stored procedures. You can automatically create all of the required SQL Server database objects by executing the aspnet_regsql tool from the command line (see Figure 1). This tool, by default, creates a new database named aspnetdb on your local instance of SQL Server.

ms379595.whidbeysecurity_fig01(en-US,VS.80).gif

Figure 1. Configuring the SqlMembershipProvider

After you create the new database, you'll want to make sure the database can be accessed by your ASP.NET application. By default, integrated security is used. Therefore, you'll want to make sure that the ASP.NET account (the NT AUTHORITY\NETWORK SERVICE account in the case of Windows Server 2003, or the ASPNET account in the case of Windows 2000 or XP) has the necessary permissions to access the aspnetdb database.

Configuring Membership Provider Properties

Both the AccessMembershipProvider and SqlMembershipProvider support several provider specific attributes:

  • applicationName—If you need to host multiple applications on the same Web server, you can use this property to isolate the users who are associated with the different applications.
  • connectionStringName—The name of a database connection string defined in the connectionStrings section of the Web configuration file.
  • description—A description of the provider definition.
  • enablePasswordReset—When true, users can reset their password to a randomly generated password.
  • enablePasswordRetrieval—When true, user passwords can be retrieved from the Membership provider.
  • passwordFormat—This property has three possible values: Clear, Encrypted, and Hashed. When passwords are hashed, the original passwords cannot be retrieved from the Membership Provider.
  • requiresQuestionAndAnswer—When true, the user must answer a password retrieval question before the user password can be reset or retrieved.
  • requiresUniqueEmail—When true, a unique e-mail address must be associated with each user.

You can use these Membership Provider attributes to control how membership information is stored and retrieved from the database. The values of these attributes can be changed in your application's Web configuration file.

For example, the passwordFormat attribute determines how passwords are stored in the database. You are provided with the option of storing clear text passwords, encrypted passwords, or password hash values. For security reasons, you might want to store hash values instead of actual passwords in the database, so that if your Web application is compromised, the hackers will not be able to steal actual user passwords.

Also notice that you can enable or prevent user passwords from being retrieved from the database by setting the enablePasswordRetrieval attribute. Again, for the sake of security, you might not want to enable users to retrieve their passwords.

Using the Web Site Administration Tool to Configure Security

The Web Site Administration Tool included with the ASP.NET 2.0 framework enables you to configure an ASP.NET application entirely through a Web page interface (see Figure 2). You can use the Web Site Administration Tool to create and manage users and roles, and control access to folders and individual pages in a Web application (The Web Site Administration Tool can also be used to configure several other aspects of a Web application).

Click here for larger image.

Figure 2. Using the Web Site Administration Tool

There are multiple ways that you can navigate to the Web Administration interface. If you are building a Web application within Visual Studio .NET 2005, you can open the Web Site Administration Tool by selecting ASP.NET Configuration from under the Website menu. If you are developing a Web application outside of Visual Studio .NET, you can navigate directly to the Web Site Administration Tool by requesting the special page WebAdmin.axd. For example, if your application is located in a virtual directory named MyWebApp on your local machine, you can open the Website Administration Tool for your application by entering the following URL in your Web browser.

https://localhost/MyWebApp/WebAdmin.axd

You can also use this latter method to access the Web Site Administration Tool for a deployed application.

Behind the scenes, the Web Site Administration Tool is made up of a set of ASP.NET pages that use the standard Login controls discussed in the next section. These pages are located in the inetpub\wwwroot\aspnet_webadmin folder. If, for any reason, these files get accidentally deleted from a server, you can automatically re-install them by executing the aspnet_regiis tool. The aspnet_regiis tool can also be used to control access to the Web Site Administration Tool. For example, using the aspnet_regiis tool you can restrict access to the Web Site Administration Tool to just the local server.

Using the Login Controls to Create Standard Security Pages

ASP.NET 2.0 contains a new set of security-related controls, known collectively as the Login controls. By taking advantage of the Login controls, you can create standard registration, login, and password recovery pages without writing any code.

You can also use the Login controls to display different information to users, depending on their roles and current authentication status. For example, the LoginView control enables you to define different templates that are displayed to members of different roles. You can use this control, for instance, to display different information to members of the Administrators role than to members of the Guests role.

Behind the scenes, the Login controls take full advantage of the Provider Model. If you have configured your application to use the AccessMembershipProvider, then the Login controls will automatically query a Microsoft Access database to retrieve membership information. If the SqlMembershipProvider is enabled, the configured SQL Server database is used by the controls.

Before using any of the Login controls, you should enable Forms Authentication for your application. You can enable Forms Authentication by modifying your application's Web configuration file, or by using the Web Site Administration Tool.

Using the Login Control

The Login control enables you to create a standard login page simply by adding a single tag to a page.

<asp:Login ID="Login1" Runat="server" />

The Login control automatically generates a standard login interface. By default, the interface is not very pretty, but you can quickly improve the Login control's appearance in Visual Studio .NET 2005 by right-clicking the control and selecting AutoFormat (see Figure 3). Notice that you get standard username and password text boxes, a "remember me" checkbox, and a submit button.

ms379595.whidbeysecurity_fig03(en-US,VS.80).gif

Figure 3. Creating a login interface with the Login control

The Login control not only provides you with the interface, it actually works! When you submit your username and password by using the Login control, your credentials are automatically validated by the configured Membership Provider.

There is a daunting list of properties associated with the Login control. The vast majority of these properties simply enable you to control different aspects of the appearance of the login interface. For example, you can use the various FailureText properties to control the content and appearance of the text that is displayed when a login attempt fails. Additionally, you can use the CreateUserUrl and PasswordRecoveryUrl properties to create links to a registration page and password recovery page.

One of the more valuable properties included with the Login control is the VisibleWhenLoggedIn property. This property enables you to automatically hide the Login control when the user is already authenticated. For example, you might want to include the Login control at the top of every page in your Web application. By using the VisibleWhenLoggedIn property, you can automatically hide the Login control just as soon as a user is authenticated.

Using the CreateUserWizard Control

The CreateUserWizard control enables you to create a standard user registration page. Simply by adding the following tag to a page, you can enable new users to register at your Web site.

 <asp:CreateUserWizard ID="CreateUserWizard1" Runat="server" />

The exact appearance of the interface generated by the CreateUserWizard depends on the settings of your application's Membership Provider. For example, the text boxes for a password question and answer appear only when the default Membership Provider's requiresQuestionAndAnswer attribute has the value true. The registration page in Figure 4 is generated when the CreateUserWizard is used with the default AspNetAccessProvider Membership Provider.

ms379595.whidbeysecurity_fig04(en-US,VS.80).gif

Figure 4. Registering new users with the CreateUserWizard control

One of the more interesting things that you can do with the CreateUserWizard control is to automatically send a registration e-mail message after the user has completed all of the registration steps. For example, you can send an e-mail message that thanks the user for registering at your Web site. The e-mail message can contain information such as the user's registered username and password.

You configure the e-mail message sent by the CreateUserWizard control by assigning values to the control's MailDefinition property. The MailDefinition property represents an instance of the MailDefinition class that contains all of the properties required for defining an e-mail message.

For example, the following CreateUserWizard control will send the contents of the RegistrationEmail.txt file as the body of the registration e-mail message whenever someone completes the registration wizard (The CreateUserWizard uses the e-mail server specified in the <smtpMail> mail section of the Web configuration file when sending e-mail messages).

 <asp:CreateUserWizard ID="CreateUserWizard1" Runat="server">
   <MailDefinition 
     BodyFileName="~/RegistrationEmail.txt" 
     From="YourSite@YourDomain.com"
     Subject="Thanks for registering!">
   </MailDefinition>
</asp:CreateUserWizard>

Within the RegistrationEmail.txt file you can use special expressions, such as <% UserName %> and <% Password %>, in order to substitute the new user's registered username and password within the body of the e-mail message.

The CreateUserWizard control's e-mail functionality also can be useful in more complicated registration scenarios in which you need to validate a user's e-mail address before you provide the user with access to your Web application. If you enable the CreateUserWizard control's AutoGeneratePassword property, then the control will randomly generate a password for a user. By taking advantage of the CreateUserWizard control's e-mail functionality, you can automatically send the randomly generated password to the user. If the user subsequently authenticates against your Web application using the sent password, then you know that the user must have supplied a valid e-mail address.

Using the PasswordRecovery Control

The PasswordRecovery control enables users of your Web application to request an e-mail reminder of their password (see Figure 5). Like the CreateUserWizard control, you define the properties of the e-mail message sent to the user with the MailDefinition property.

ms379595.whidbeysecurity_fig05(en-US,VS.80).gif

Figure 5. E-mailing a password with the PasswordRecovery control

For example, the following tag adds a PasswordRecovery control to a page which sends an e-mail message from the YourSite@YourDomain.com e-mail account.

 <asp:PasswordRecovery ID="PasswordRecovery1" Runat="server">
   <MailDefinition 
      From="YourSite@YourDomain.com" 
      Subject="Password Reminder">
   </MailDefinition>
 </asp:PasswordRecovery>

The PasswordRecovery control has different behaviors, depending on the configuration of the default Membership Provider. When the enablePasswordRetrieval attribute has the value true, and the passwordFormat attribute does not have the value Hashed, the user's original clear text password is sent in the e-mail message. In the case of almost every other combination of attribute values, the password is reset to a randomly generated sequence of characters before being sent to the user.

Using the ChangePassword Control

The ChangePassword control, as you might guess, enables users to change their registered passwords. The control renders text boxes for entering the original password and entering a new password (see Figure 6).

ms379595.whidbeysecurity_fig06(en-US,VS.80).gif

Figure 6. Changing your password with the ChangePassword control

Like the CreateUserWizard and PasswordRecovery controls, the ChangePassword control includes a MailDefinition property. When values are assigned to the MailDefinition property, the ChangePassword control automatically sends an e-mail message to the user when a password is successfully changed.

The following tag declares an instance of the ChangePassword control and sets the MailDefinition property.

 <asp:ChangePassword ID="ChangePassword1" Runat="server">
   <MailDefinition 
     BodyFileName="~/ChangePasswordEmail.txt" 
     From="YourSite@YourDomain.com"
     Subject="Your Updated Password">
   </MailDefinition>
</asp:ChangePassword> 

The BodyFileName property contains the path to a text file that contains the body of the e-mail message that is sent to the user. Within the text file, you can use special expressions such as <% UserName %> and <% Password %> to display the user's registered username and modified password in the e-mail message.

Using the LoginName and LoginStatus Controls

The LoginName and LoginStatus controls enable you to display information about the current authentication status of a user. After a user has logged onto your application, the LoginName control displays the user's registered username. If a user has not been authenticated with Forms Authentication, the LoginName control displays absolutely nothing. Here's how you declare the LoginName control on a page.

<asp:LoginName ID="LoginName1" Runat="server" />

The LoginStatus, on the other hand, enables a user to log in or log off your Web application. The control displays one of two links. If the user is not authenticated, a link to the Login.aspx page is displayed. If the user has already been authenticated, a link that enables the user to log off is displayed. Here's how you declare the LoginStatus control.

<asp:LoginStatus ID="LoginStatus1" Runat="server" />

Using the LoginView Control

The final Login control, the LoginView control, enables you to display different content depending on the role of the current user. For example, many Web sites display different information on their home page, depending on whether the user is a new user or a registered user. New users might get an overview of the purpose of the Web site, while registered users can view information that is tailored specifically for them.

Here's how you can use the LoginView control to display different content to an anonymous user than the content which is displayed to an authenticated user.

<asp:LoginView ID="LoginView1" Runat="server">
   <LoggedInTemplate>
     Welcome back <asp:LoginName ID="LoginName1" Runat="server" />
  </LoggedInTemplate>
  <AnonymousTemplate>
     Welcome to our Web site! If you were a registered user, 
     you could view some really interesting stuff right now!
  </AnonymousTemplate>
</asp:LoginView>

An anonymous user sees all the content contained in the AnonymousTemplate. An authenticated user, on the other hand, sees all the content contained in the LoggedInTemplate.

If you enable custom roles for your Web application, you can use the LoginView control to display content that can only be viewed by members of particular roles. For example, imagine that you used the Web Site Administration Tool to create a new role named Administrators. In that case, you could use the LoginView control to display content that can only be viewed by members of the Administrators role, like this.

 <asp:LoginView ID="LoginView1" Runat="server">
   <RoleGroups>
     <asp:RoleGroup Roles="Administrators">
       <ContentTemplate>
         Secret stuff for administrators!
       </ContentTemplate>
     </asp:RoleGroup>
   </RoleGroups>
   <LoggedInTemplate>
     Welcome back <asp:LoginName ID="LoginName1" Runat="server" />
   </LoggedInTemplate>
   <AnonymousTemplate>
     Welcome to our Web site! If you were a registered user, 
     you could view some really interesting stuff right now!
  </AnonymousTemplate>
</asp:LoginView>

Members of the Administrators role would be able to view any content contained in the <ContentTemplate> associated with the Administrators RoleGroup. A member of the Administrators role, however, would not be able to view the content declared within either the LoggedInTemplate or Anonymous template. You can only see the content of a single template, even when more than one template applies to you.

Working Directly with the Membership API

There are situations in which you will need a greater level of control over membership than what is provided by either the Web Site Administration Tool or the Login controls. In these situations, you can work directly with the Membership API.

The Membership API is exposed through the Membership class. The Membership class includes methods that enable you to do such things as create new users, change passwords, and search for users that match a particular criterion. Behind the scenes, the Login controls use these methods to interact with the configured Membership Provider.

Here is a list of some of the more important methods of the Membership class:

  • CreateUser—Enables you to create new users.
  • DeleteUser—Enables you to delete existing users.
  • FindUsersByEmail—Enables you to retrieve a collection of users that match a certain e-mail address.
  • FindUsersByName—Enables you to retrieve a collection of users that match a certain username.
  • GeneratePassword—Enables you to generate a random password.
  • GetAllUsers—Enables you to retrieve all users stored in the Membership Provider.
  • GetNumberOfUsersOnline—Enables you to return the number of users currently accessing your Web application.
  • GetUser—Enables you to retrieve the membership information associated with the current user, or enables you to retrieve membership information associated with a user who has the supplied username.
  • GetUsernameByEmail—Enables you to retrieve a username for a user with a certain e-mail address.
  • UpdateUser—Enables you to update a particular user's information.
  • ValidateUser—Enables you to authenticate a user against the Membership Provider.

These methods are extremely powerful. For example, by taking advantage of the CreateUser method, you can create a new user with a single line of code.

// C#
Membership.CreateUser( "Ruth", "Secret" );

FakePre-d0f49d5117d54e09a5196b2ffb784d5a-f77052386783411dbdfd84a634ec8f1c

This statement creates a new user named Ruth, with the password Secret.

Several of the Membership methods, such as the GetAllUsers and FindUsersByName, return collections of MembershipUser objects. The MembershipUser class represents information about a particular user. This class has the following properties:

  • Comment—Represents an arbitrary comment associated with the user.
  • CreationDate—Represents the date when the user was created.
  • Email—Represents the user's e-mail address.
  • IsApproved—Represents whether or not the user has been approved.
  • IsOnline—Represents whether or not the user is currently accessing the Web application.
  • LastActivityDate—Represents the date when the user last accessed the Web application.
  • LastLoginDate—Represents the date when the user was last authenticated.
  • LastPasswordChangedDate—Represents the date when the user password was last changed.
  • PasswordQuestion—Represents the password question used with password question and answer.
  • Provider—Represents the Membership Provider.
  • Username—Represents the username.

The MembershipUser class also includes the following methods:

  • ChangePassword—Enables you to change the user's password.
  • ChangePasswordQuestionAndAnswer—Enables you to change the password question and answer.
  • GetPassword—Enables you to retrieve the user's password.
  • ResetPassword—Enables you to reset the user's password.

You can use the properties of the MemberUser class to display information about the users of your Web application. For example, the ASP.NET page in Listing 1 displays the username, e-mail address, last activity date, and online status for every user in a GridView control (see Figure 7).

ms379595.whidbeysecurity_fig07(en-US,VS.80).gif

Figure 7. Displaying membership information with the Membership API

Listing 1. DisplayMembers.aspx (C#)

<%@ Page Language="C#" %>
<script runat="server">

void Page_Load() {
    grdUsers.DataSource = Membership.GetAllUsers();
    grdUsers.DataBind();
}

</script>

<html>
<head runat="server">
    <title>Display Members</title>
</head>
<body>
<form runat="Server">

<asp:GridView ID="grdUsers" AutoGenerateColumns="false" Runat="Server">
<Columns>
    <asp:BoundField HeaderText="Username" DataField="Username" />
    <asp:BoundField HeaderText="Email" DataField="Email" />
    <asp:BoundField HeaderText="Last Activity Date" 
     DataField="LastActivityDate" DataFormatString="{0:d}" />
    <asp:CheckBoxField HeaderText="Is Online" DataField="IsOnline" />
</Columns>
</asp:GridView>

</form>
</body>
</html>

Listing 1. DisplayMembers.aspx (Visual Basic .NET)

<%@ Page Language="VB" %>
<script runat="server">

    Sub Page_Load()
        grdUsers.DataSource = Membership.GetAllUsers()
        grdUsers.DataBind()
    End Sub

</script>

<html>
<head id="Head1" runat="server">
    <title>Display Members</title>
</head>
<body>
<form id="Form1" runat="Server">

<asp:GridView ID="grdUsers" AutoGenerateColumns="false" Runat="Server">
<Columns>
    <asp:BoundField HeaderText="Username" DataField="Username" />
    <asp:BoundField HeaderText="Email" DataField="Email" />
    <asp:BoundField HeaderText="Last Activity Date" 
     DataField="LastActivityDate" DataFormatString="{0:d}" />
    <asp:CheckBoxField HeaderText="Is Online" DataField="IsOnline" />
</Columns>
</asp:GridView>

</form>
</body>
</html>

The users are bound to the GridView control within the Page_Load method. The list of users is retrieved by using the GetAllUsers method of the Membership class.

Conclusion

The ASP.NET 2.0 framework includes significant new security features that will appeal to both Web site administrators and developers. The new Web Site Administration Tool enables you to create and manage users entirely through a Web form interface. The new Login controls enable you to build standard Web site security pages without writing a single line of code. Finally, the Membership API provides you with a powerful set of methods for manipulating membership information through code.

 

About the author

Stephen Walther wrote the best-selling book on ASP.NET, ASP.NET Unleashed. He was also the architect and lead developer of the ASP.NET Community Starter Kit, a sample ASP.NET application produced by Microsoft. He has provided ASP.NET training to companies across the United States, including NASA and Microsoft, through his company Superexpert (https://www.superexpert.com).

© Microsoft Corporation. All rights reserved.