- Membership
- Security Server Controls
- Role Manager
- Cookieless Forms Authentication
- The Web Site Administration Tool
- Summary
Security Server Controls
The new Membership infrastructure feature of ASP.NET simplifies the management and storage of user credentials. Using APIs, such asMembership.ValidateUser(), for Forms Authentication definitely makes things easy. However, some techniques are made even easier through the use of several new security-related server controls. For example, you can author your own login page with zero lines of code by using the new Login control or create users using the new CreateUserWizard control.
The CreateUserWizard Control
Earlier in the chapter we showed the code required to create a new user. In the alpha version of ASP.NET (then code-named "Whidbey") this was the only way to create new users. In the beta version the new CreateUserWizard control can be used instead for a no-code alternative.
The CreateUserWizard control, <asp:CreateUserWizard runat= "server" />, uses the new Wizard control and allows for multiple steps to be defined during the user creation process. Figure 6.6 shows the CreateUserWizard control in design time. As you can see, the options available are specific to Membership, but we could just as easily add another step to the control for collecting more user information, such as first name, last name, and so on. Listing 6.9 shows the source to the control_createuser.aspx page.
Example 6.9. Using the CreateUserWizard Control
<html> <body style="FONT-FAMILY: Verdana"> <H1>Validate Credentials</H1> <hr /> <form id="Form1" runat="server"> <asp:CreateUserWizard runat="server" /> </form> </body> </html>
Figure 6.6 The CreateUserWizard control
The Login Control
Figure 6.7 shows a control_login.aspx page that authenticates the user's credentials against the default Membership provider and uses the new <asp:Login runat="server" /> control. As you can see in Figure 6.7, it looks nearly identical to the login page we built with the Membership APIs. Listing 6.10 shows the source to the control_login.aspx page.
Example 6.10. Using the Login Control
<html> <body style="FONT-FAMILY: Verdana"> <H1>Validate Credentials</H1> <hr /> <form id="Form1" runat="server"> <asp:Login id="Login1" runat="server" /> </form> </body> </html>
Figure 6.7 The login control
When the username and password are entered, this control will automatically attempt to log in the user by calling Membership .ValidateUser(). If successful, the control will then call the necessary FormsAuthentication.RedirectFromLoginPage API to issue a cookie and redirect the user to the page he or she was attempting to access. In other words, all the code you would have needed to write in ASP.NET 1.1 is now neatly encapsulated in a single server control!
The <asp:Login runat="server" /> control automatically hides itself if the user is logged in. This behavior is determined by the AutoHide property, set to True by default. If the login control is used with Forms Authentication and hosted on the default login page (specified in the configuration for Forms Authentication) the control will not auto-hide itself.
We can further customize the login control's UI. To preview one UI optionwe can't cover all of them in depth in this bookright-click on the login control within Visual Studio 2005 and select Auto Format. This will bring up the dialog box shown in Figure 6.8.
Figure 6.8 The Auto Format dialog
Once you've chosen an auto-format template, such as Classic, you can see the changes in the login control (see Listing 6.11).
Example 6.11. A Formatted Login Control
<asp:Login id="Login1" runat="server" font-names="Verdana" font-size="10pt" bordercolor="#999999" borderwidth="1px" borderstyle="Solid" backcolor="#FFFFCC"> <TitleTextStyle Font-Bold="True" ForeColor="#FFFFFF" BackColor="#333399"> </TitleTextStyle> </asp:Login>
If you desire more control over the display of the control, right-click on the control, or from the Common Tasks dialog, select Convert to Template. You'll see no changes in the rendered UI of the control. However, you will see a notable difference in the declarative markup generated for the control. For brevity we are not including the updated markup. [9] What you will see is a series of templates that allow you to take 100% control over the UI rendering of the control. Note that it is important that the IDs of the controls within these templates remain because the control expects to find these IDs.
While the login control simplifies authoring the login page, several other controls help us display content to users based on their login status. Let's take a look at the login status control first.
The Login Status Control
The login status control, <asp:LoginStatus runat="server" />, is used to display whether the user is logged in or not. When the user is not logged in, the status displays a Login link (see Figure 6.9). When the user is logged in, the status displays a Logout link (see Figure 6.10).
Figure 6.9 The login status control when the user is not logged in
Figure 6.10 The login status control when the user is logged in
Listing 6.12 shows the code required.
Example 6.12. The Login Status Control
<html> <body style="FONT-FAMILY: Verdana"> <h1>Login Status</h1> <hr /> <form runat="server"> <asp:LoginStatus id="LoginStatus1" runat="server" /> </form> </body> </html>
By default the text displayed for the link is "Login" when the user is not logged in and "Logout" when the user is logged in. [10] However, this text can easily be changed; you simply need to change the LoginText or LogoutText properties of the control:
<asp:LoginStatus id="Loginstatus1" runat="server" LoginText="Please log in" LogoutText="Please log out" />
Other properties can also be set to control the behavior of this control. For example, you can use the LoginImageUrl and the LogoutImageUrl to use images rather than text for displaying the login status. Finally, there are two properties for controlling the behavior upon logout:
-
LogoutAction: This property specifies the behavior when the logout button is clicked. Options include Refresh, Redirect, and RedirectToLoginPage.
-
LogoutPageUrl: When the LogoutAction is set to Redirect, the LogoutPageUrl is the location to which the browser is redirected.
Whereas <asp:LoginStatus runat="server" /> provides an easy way for the user to log in and log out, another server control, <asp:LoginView runat="server" />, allows us to easily determine what content is shown to the user based on his or her login status.
The Login View Control
The <asp:LoginView runat="server" /> server control is used to display different output depending on the login status of the user. Furthermore, the control can also be used to display different content based on the role(s) the user belongs to. Figure 6.11 shows an example of what the control might display for an anonymous user. The code that generates this page appears in Listing 6.13.
Example 6.13. Using the Login View Control
<html> <body style="FONT-FAMILY: Verdana"> <h1>Login View and Login Name Controls</h1> <hr /> <form runat="server"> <asp:LoginView id="Loginview1" runat="server"> <anonymoustemplate> Unknown user please <asp:LoginStatus runat="server" logintext="login" /> </anonymoustemplate> <rolegroups> <asp:rolegroup roles="Admin"> <contenttemplate> This is admin only content! </contenttemplate> </asp:rolegroup> </rolegroups> <loggedintemplate> You are logged in as: <asp:LoginName id="LoginName1" runat="server" /> </loggedintemplate> </asp:LoginView> </form> </body> </html>
Figure 6.11 The login view for an anonymous user
In this code you can see that two templates are defined for the <asp:LoginView runat="server" /> control:
-
<anonymoustemplate /> is used to control the displayed content when the user is not logged in.
-
<loggedintemplate /> is used to control the displayed content when the user is logged in.
In addition to the templates, there is also a special <rolegroups /> section that allows us to create different templates that are displayed if the user is in a corresponding role or roles. If the user is logged in but no roles apply, the <loggedintemplate /> is used. [11]
You'll notice that we also made use of another control in Listing 6.13: <asp:LoginName runat="server" />. This control simply displays the name of the logged-in user. If the user is not logged in, the control does not render any output.
The last security-related server control is <asp:PasswordRecovery runat="server" />, which is used to help users obtain their forgotten passwords.
The Password Recovery Control
The <asp:PasswordRecovery runat="server" /> control works in conjunction with the Membership system to allow users to easily recover their passwords. [12]
The <asp:PasswordRecovery runat="server" /> control relies on the <smtpMail /> configuration options to be correctly set to a valid SMTP serverthe control will mail the password to the user's e-mail address. By default, the <smtpMail /> section will have the SMTP mail server set to localhost and the port set to 25 (the default SMTP port).
Similar to <asp:Login runat="server" />, this control supports auto-format and full template editing. Assuming we select an auto-format template, such as Classic, and use the default Membership settings, we should see the page shown in Figure 6.12.
Figure 6.12 Password recovery
Listing 6.14 presents the code that generates this page (auto-formatting removed).
Example 6.14. Using the Password Recovery Control
<html> <body style="FONT-FAMILY: Verdana"> <H1> Password Recovery <hr /> </H1> <form id="Form1" runat="server"> <asp:PasswordRecovery runat="server"> <maildefinition from="admin@mywebsite.com" /> </asp:PasswordRecovery> </form> </body> </html>
If we attempt to use the control with the default Membership settingswhich do not allow password recoverywe will receive the following error:
-
"Your attempt to retrieve your password was not successful. Please try again."
To allow us to recover the password, we need to change some of the default membership settings. Below are the necessary changes to the <membership /> configuration settings to allow for password recovery:
-
enablePasswordRetrieval="True"
-
passwordFormat="Clear"
The enablePasswordRetrieval attribute must be set to True to allow for password retrieval, and the passwordFormat attribute must be set to either Clear or Encrypted. [13] Another alternative is that when enable PasswordReset is set to True, the new password can be e-mailed to the user.
In addition to configuring the <membership /> configuration settings, we must specify the <maildefinition /> element of the <asp:PasswordRecovery runat="server" /> control. The <maildefinition /> names the address from whom e-mails are sent.
Finally, we can also use the <asp:PasswordRecovery runat="server" /> control to retrieve the user's password using the question/answer support of Membership (see Figure 6.13). The control still requires that we enter the username first, but before simply mailing the password it will first also request the answer to the user's question.
Figure 6.13 Password recovery with question and answer
This behavior is forced by setting the <membership /> configuration setting requiresQuestionAndAnswer to true (the default is false). [14] Note that this configuration change is in addition to changing the enablePasswordRetrieval to true and setting the passwordFormat to a value other than Hashed.
Managing and storing user credentials are only one part of securely controlling access to resources within your site. In addition to validating who the user is, you need to determine whether the user is allowed to access the requested resource. The process of validating credentials is known as authentication; authorization is the process of determining whether the authenticated user is allowed to access a particular resource.
ASP.NET 1.x already provides authorization facilities, but just as we have shown with Membership, there is more simplification to be done.