ptg 1224 CHAPTER 27 Using ASP.NET Membership Authorizing Files by Location By default, authorization rules are applied to all pages in a folder and all subfolders. However, you also have the option of using the location element with the authorization element. The location element enables you to apply a set of authorization rules to a folder or page at a particular path. For example, imagine that you want to password-protect one, and only one, page in a folder. In that case, you can use the location element to specify the path of the single page. The web configuration file in Listing 27.13 password-protects a page named Secret.aspx. LISTING 27.13 Web.Config Protecting a File <?xml version=”1.0”?> <configuration> <system.web> <authentication mode=”Forms” /> </system.web> <location path=”Secret.aspx”> <system.web> <authorization> <deny users=”?”/> </authorization> </system.web> </location> </configuration> You also can use the location element to apply configuration settings to a particular subfolder. For example, the web configuration file in Listing 27.14 password-protects a folder named SecretFiles. LISTING 27.14 Web.Config Protecting a Folder <?xml version=”1.0”?> <configuration> <system.web> <authentication mode=”Forms” /> </system.web> <location path=”SecretFiles”> <system.web> From the Library of Wow! eBook ptg 1225 Configuring Authorization 27 <authorization> <deny users=”?”/> </authorization> </system.web> </location> </configuration> Using Authorization with Images and Other File Types Authorization rules are applied only to files mapped into the ASP.NET Framework. The Visual Web Developer web server maps all file types to ASP.NET Framework. Internet Information Server, on the other hand, maps only particular file types to ASP.NET Framework. If you use Internet Information Services, and you add an image to a password-protected folder, users aren’t blocked from requesting the image. By default, authorization rules apply only to ASP.NET file types such as ASP.NET pages. Files such as images, Microsoft Word documents, and classic ASP pages are ignored by ASP.NET Framework. If you need to password-protect a particular type of static file, such as an image or Microsoft Word document, you need to map the file’s extension to the ASP.NET ISAPI extension. For example, follow these steps to enable authorization for .gif image files: 1. Open Internet Information Services by selecting Start, Control Panel, Administrative Tools, Internet Information Services (IIS) Manager. 2. In the tree on the left, click a particular website or virtual directory. A list of configu- ration icons appears in the main content area. 3. Open the Mappings page by double-clicking the Handler Mappings icon located under the IIS configuration group. The Handler Mappings dialog window appears (see Figure 27.3). 4. Click the Add Script Map button to open the Add Script Map dialog box. 5. In the Request Path field, enter *.gif. 6. In the Executable field, enter the path to the ASP.NET ISAPI DLL. (You can copy and paste this path from the Application Mapping for the .aspx extension.) 7. In the Name field, enter a mapping name such as GIF-ISAPI-4.0. After you complete these steps, requests for .gif images are passed to ASP.NET Framework. You can then use authentication and authorization rules with .gif images. You can complete the same sequence of steps to password-protect other static file types, such as Microsoft Word documents, Excel spreadsheets, or video files. From the Library of Wow! eBook ptg 1226 CHAPTER 27 Using ASP.NET Membership FIGURE 27.3 The Mappings configuration in Internet Information Services (Windows 7). Using ASP.NET Membership ASP.NET Membership enables you to create new users, delete users, and edit user proper- ties. It’s the framework used behind the scenes by the Login controls. ASP.NET Membership picks up where Forms authentication leaves off. Forms authentica- tion 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: . SqlMembershipProvider—Stores user information in a Microsoft SQL Server database. . ActiveDirectoryMembershipProvider—Stores user information in the Active Directory or an Active Directory Application Mode server. 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 require- ments for a valid membership password. Finally, we build a custom Membership provider. It is an XmlMembershipProvider that stores membership information in an XML file. From the Library of Wow! eBook ptg 1227 Using ASP.NET Membership 27 Using the Membership Application Programming Interface The main application programming interface for ASP.NET Membership is the Membership class. This class supports the following methods: . CreateUser—Enables you to create a new user. . DeleteUser—Enables you to delete an existing user. . FindUsersByEmail—Enables you to retrieve all users who have a particular email address. . FindUsersByName—Enables you to retrieve all users who have a particular username. . GeneratePassword—Enables you to generate a random password. . GetAllUsers—Enables you to retrieve all users. . GetNumberOfUsersOnline—Enables you to retrieve a count of all users online. . GetUser—Enables you to retrieve a user by username. . GetUserNameByEmail—Enables you to retrieve the username for a user with a particu- lar email address. . UpdateUser—Enables you to update a user. . ValidateUser—Enables you to validate a username and password. This class also supports the following event: . ValidatingPassword—Raised when a user password is validated. You can handle this event to implement a custom validation algorithm. You can use the methods of the Membership class to administer the users of your website. For example, the page in Listing 27.15 displays a list of every registered user (see Figure 27.4). LISTING 27.15 ListUsers.aspx <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” > <head id=”Head1” runat=”server”> <title>List Users</title> </head> <body> <form id=”form1” runat=”server”> <div> <asp:GridView id=”grdUsers” From the Library of Wow! eBook ptg 1228 CHAPTER 27 Using ASP.NET Membership FIGURE 27.4 Displaying registered users. In Listing 27.15, an ObjectDataSource control represents 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, you can retrieve the number of users currently online by calling the GetNumberOfUsersOnline() method. The custom control in Listing 27.16 displays the value returned by this method. DataSourceID=”srcUsers” Runat=”server” /> <asp:ObjectDataSource id=”srcUsers” TypeName=”System.Web.Security.Membership” SelectMethod=”GetAllUsers” Runat=”server” /> </div> </form> </body> </html> From the Library of Wow! eBook ptg 1229 Using ASP.NET Membership 27 NOTE Chapter 36, “Building Custom Controls,” discusses custom control building. LISTING 27.16 UsersOnline.cs using System; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls { /// <summary> /// Displays Number of Users Online /// </summary> public class UsersOnline : WebControl { protected override void RenderContents(HtmlTextWriter writer) { writer.Write(Membership.GetNumberOfUsersOnline()); } } } The page in Listing 27.17 uses the UsersOnline control to display the number of users currently online (see Figure 27.5). LISTING 27.17 ShowUsersOnline.aspx <%@ Page Language=”C#” %> <%@ Register TagPrefix=”custom” Namespace=”myControls” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” > <head id=”Head1” runat=”server”> <title>Show UsersOnline</title> </head> <body> <form id=”form1” runat=”server”> <div> From the Library of Wow! eBook ptg 1230 CHAPTER 27 Using ASP.NET Membership FIGURE 27.5 Display number of users online. How many people are online? <br /> <custom:UsersOnline id=”UsersOnline1” Runat=”server” /> </div> </form> </body> </html> 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 represents a particular website member. This class supports the following properties: From the Library of Wow! eBook ptg 1231 Using ASP.NET Membership 27 . Comment—Enables you to associate a comment with the user. . CreationDate—Enables you to get the date when the user was created. . Email—Enables you to get or set the user’s email address. . IsApproved—Enables you to get or set whether the user is approved and her account is active. . IsLockedOut—Enables you to get the user’s lockout status. . IsOnline—Enables you to determine whether the user is online. . LastActivityDate—Enables you to get or set the date of the user’s last activity. This date is updated automatically with a call to CreateUser(), ValidateUser(), or GetUser(). . LastLockoutDate—Enables you to get the date that the user was last locked out. . LastLoginDate—Enables you to get the date that the user last logged in. . LastPasswordChangedDate—Enables you to get the date that the user last changed her password. . PasswordQuestion—Enables you to get the user’s password question. . ProviderName—Enables you to retrieve the name of the Membership provider associ- ated with this user. . ProviderUserKey—Enables you to retrieve a unique key associated with the user. In the case of the SqlMembershipProvider, this is the value of a GUID column. . UserName—Enables you to get the name of the user. 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, you need to call a method. The MembershipUser class supports the following methods: . ChangePassword—Enables you to change a user’s password. . ChangePasswordQuestionAndAnswer—Enables you to change a user’s password ques- tion and answer. . GetPassword—Enables you to get a user’s password. . ResetPassword—Enables you to reset a user’s password to a randomly generated password. . UnlockUser—Enables you to unlock a user account that has been locked out. From the Library of Wow! eBook ptg 1232 CHAPTER 27 Using ASP.NET Membership Encrypting and Hashing User Passwords Both of the default Membership providers included in the ASP.NET Framework enable you to store user passwords in three ways: . Clear—Passwords are stored in clear text. . Encrypted—Passwords are encrypted before they are stored. . Hashed—Passwords are not stored. Only the hash values of passwords are stored. (This is the default value.) You configure how passwords are stored by setting the passwordFormat attribute in the web configuration file. For example, the web configuration file in Listing 27.18 configures the SqlMembershipProvider to store passwords in plain text. LISTING 27.18 Web.Config <?xml version=”1.0”?> <configuration> <system.web> <authentication mode=”Forms” /> <membership defaultProvider=”MyProvider”> <providers> <add name=”MyProvider” type=”System.Web.Security.SqlMembershipProvider” passwordFormat=”Clear” connectionStringName=”LocalSqlServer”/> </providers> </membership> </system.web> </configuration> 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. From the Library of Wow! eBook ptg 1233 Using ASP.NET Membership 27 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 27.19 configures the SqlMembershipProvider to encrypt passwords. 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 27.19 Web.Config <?xml version=”1.0”?> <configuration> <system.web> <authentication mode=”Forms” /> <membership defaultProvider=”MyProvider”> <providers> <add name=”MyProvider” type=”System.Web.Security.SqlMembershipProvider” passwordFormat=”Encrypted” connectionStringName=”LocalSqlServer”/> </providers> </membership> <machineKey decryption=”AES” decryptionKey=”306C1FA852AB3B0115150DD8BA30821CDFD1 ➥ 25538A0C606DACA53DBB3C3E0AD2” /> </system.web> </configuration> From the Library of Wow! eBook . the ASP. NET ISAPI DLL. (You can copy and paste this path from the Application Mapping for the .aspx extension.) 7. In the Name field, enter a mapping name such as GIF-ISAPI -4 . 0. After you complete. rules apply only to ASP. NET file types such as ASP. NET pages. Files such as images, Microsoft Word documents, and classic ASP pages are ignored by ASP. NET Framework. If you need to password-protect. Wow! eBook ptg 1227 Using ASP. NET Membership 27 Using the Membership Application Programming Interface The main application programming interface for ASP. NET Membership is the Membership class.