19.1 Authentication

Authentication is the first of three fundamental functions necessary to secure a web application. (The other two functions are authorization and impersonation, as described shortly.) Authentication is the process of ensuring that clients are who they claim to be. Authentication is accomplished using credentials, or some form of identification. The requesting client presents the credentials to IIS and the ASP.NET application, usually in the form of a username and password.

The credentials are then validated against some authority. Depending on how authentication is configured, that authority might be Windows 2000/XP/2003 security or it might be a store of names, passwords, and rights, maintained in a configuration file such as web.config, a relational database such as SQL Server, or an XML file.

Authentication is not required. If no authentication is performed, then the client is an anonymous user. By default, all web sites allow anonymous access. However, if you need to restrict access to any part of the web site, authentication is a necessary step.

If the system cannot identify a user based on the credentials presented, and if anonymous users are disallowed, then access is denied. If the system can identify the user, than that user is considered an authenticated identity and allowed to proceed on to authorization. Sometimes the identity is known as a principal.

Authentication is provided through code modules called authentication providers. Authentication providers are enabled using the ASP.NET configuration files, either machine.config or the copy of web.config in the application virtual root directory. (For a complete description of the configuration files, see Chapter 20.)

A typical entry in a configuration file to enable authentication would look like the following:

<configuration>    <system.web>       <authentication mode="Forms" />    </system.web> </configuration>

The mode attribute determines which authentication provider is used. There are four possible values for the mode attribute, as shown in Table 19-1. Each of these authentication modes will be described in the following sections.

Table 19-1. Values of the Authentication key's mode attribute

Mode value

Description

Windows

Windows authentication will be used in conjunction with IIS. This is the default.

Forms

Unauthenticated requests are redirected to an HTML form, which gathers credentials from the user and submits them to the application for authentication.

Passport

Centralized commercial authentication service offered by Microsoft to web site developers, providing single logon across web sites.

None

No authentication will be performed. Enables anonymous access.

19.1.1 Anonymous Access

Anonymous access occurs when a web application does not need to know the identity of users. In this case, credentials are not requested by IIS and authentication is not performed. Allowing anonymous access is the default configuration for web sites.

To configure IIS to disallow anonymous authentication, use either the Computer Management console or the Internet Services console. Click on the Start button, then Settings Control Panel, then Administrative Tools. Now you have a choice of two ways to get to the same place. Click on either Internet Services Manager or Computer Management.

From either, you get the Microsoft Management Console (MMC), which is used throughout Windows for displaying and controlling many system functions. In the left pane is a hierarchical tree structure showing resources relevant to the aspect(s) of the computer being managed. The right pane contains the child nodes of the currently selected node on the left.

From Computer Management, select "Services and Applications" in the left-hand pane, then drill down to Internet Information Services, then Default Web Site. From Internet Services Manager go directly to Internet Information Services, then Default Web Site. At this point, you can right-click on Default Web Site to set the properties for the entire server (i.e., all the web applications on the server), or you can drill down further to the application virtual directory to set the properties for a specific application. In either case, right-clicking will present a menu, from which you select Properties. Select the Directory Security tab. This tab is shown in Figure 19-2.

Figure 19-2. Directory Security tab
figs/pan2_1902.gif

The Directory Security tab has sections for enabling server certificates and imposing restrictions based on IP address and domain name. (This latter section will be available only for Windows 2000 Server and Windows 2003, but will be grayed out for Windows 2000 Professional and Windows XP Professional.)

Click on the Edit button in the "Anonymous access and authentication control" section. You will get the dialog box shown in Figure 19-2.

Figure 19-3. Authentication Methods dialog box
figs/pan2_1903.gif

If the "Anonymous access" checkbox is checked, then any request will be accepted by IIS without credentials being requested by IIS and with no authentication performed. This is the default configuration for web sites. (This assumes that the IP address or domain name is not restricted in the Directory Security tab shown in Figure 19-1.)

Since all requests made to IIS must have credentials, anonymous requests are assigned to a standard user account. This account defaults to IUSR_MachineName, where MachineName is the name of the web server. You can change the account assigned to anonymous access by clicking on the Edit button in that section. The IUSR_MachineName account is a built-in account, created when IIS is installed on the machine. It has a very limited set of permissions just enough to allow access to the web site.

Anonymous access is appropriate if your application has no need to know the username or password of the person or application calling on the application, and if the information or service contained in the application is considered public. It is also possible to personalize a site without requiring login through the use of cookies. This would be useful where the content on the site is public, but you want to preserve user preferences or previous selections.

Of all the security configurations available to a web site, anonymous access provides the best performance, although it is also the least secure.

19.1.2 Windows Authentication

Windows authentication offers the developer a way to leverage the security built into the Windows 2000/XP/2003 platform and the NTFS filesystem. It takes advantage of the security built into IIS. Using Windows authentication, a high level of security can be built into an ASP.NET application with little or no code being written by the developer. The trade-off is that Windows authentication only works if the client is using a Windows platform and already has a user account on the web server or in the Windows domain to which the web server belongs.

To configure IIS for Windows authentication, follow the steps above for configuring IIS for anonymous access, shown in Figures Figure 19-1 and Figure 19-2. Uncheck the "Anonymous access" checkbox. Check one or more of the checkboxes under "Authenticated access."

If more than one type of authentication access is checked, then IIS will first attempt to use Integrated Windows authentication, if it is checked. If that fails, it will then attempt Digest authentication, if that is checked. Finally, if all else fails, it will use Basic authentication.

In order to use the Windows identity that IIS authenticates with ASP.NET, you must include the following section in the appropriate web.config configuration file:

<configuration>    <system.web>       <authentication mode="Windows" />    </system.web> </configuration>

There are three types of Windows authentication: basic, digest, and integrated Windows authentication. These are described in the following sections.

19.1.2.1 Role-based security

Windows 2000/XP/2003 provides role-based security. In this security scheme, roles, also known as groups, are defined. A role defines the range of actions and access that is permitted to users assigned to the role. Users are assigned to one or more roles, or groups. For example, if a user is a member of the Administrator role, then that person will have complete access to the computer and all its resources. If a user is a member only of the Guest group, then he will have very few permissions.

Groups and users are assigned by going to Control Panel, clicking on Administrative Tools, then clicking on Computer Management. You will see the MMC console shown in Figure 19-4.

Figure 19-4. Groups in the Computer Management console
figs/pan2_1904.gif

All the groups shown in Figure 19-3 were installed by default. All are standard built-in groups, except for the three beginning with the name ATH13, which is the name of the server from which the screen shot was taken, and Debugger Users and VS Developers, which were installed by Visual Studio.NET.

Windows users log in to the operating system, providing a username and password. These constitute their credentials. At login time, those credentials are authenticated by the operating system. Once their credentials are verified, they will have certain permissions assigned, depending on which role(s) they have been assigned to. As you will see shortly, these credentials and roles are used by ASP.NET if the web application makes use of Windows authentication.

When a client requests an ASP.NET page or web service, all the requests are handled by IIS. If Windows authentication is the currently configured authentication scheme, then IIS hands off the authentication chores to the Windows NT, Windows 2000, Windows XP operating system. The user is authenticated based on the credentials that were presented when they first logged into their Windows system. These credentials are verified against the Windows user accounts either contained on the web server or on the domain controller that handles the web server.

19.1.2.2 Basic authentication

Basic authentication is the simplest and least secure type of Windows authentication. In this type of authentication, the browser presents a standard Windows-supplied dialog box to the user for entry of credentials, consisting of a username and password. These credentials are then compared against valid user accounts either on the domain server or on the local machine. If the credentials compare, then the user is authenticated and access to the requested resource is provided.

The reason that basic authentication is the least secure method of authentication is that the username and password are sent to the server encoded as a Base64 string. However, they are not encrypted. The username and password are available to your application code in clear text. A skilled person using a network sniffer can easily intercept and extract the username and password. Therefore, basic authentication is best suited for those applications where a high level of security is not a requirement, or no other authentication method will work.

It is possible to use basic authentication in conjunction with Secure Sockets Layer (SSL) to achieve a high level of security. This encrypts the information passed over the network and prevents the password from being deciphered, although the performance hit from SSL is significant.

To set the authentication method to Basic, refer back to Figure 19-2. Uncheck "Anonymous access," "Digest authentication," and "Integrated Windows authentication," if any of them are checked. Then check "Basic authentication." That is all that is necessary to implement basic authentication in IIS. To configure ASP.NET, include the following section in the relevant web.config configuration file:

<configuration>    <system.web>       <authentication mode="Windows" />    </system.web> </configuration>

By default, the local domain of the web server is active and is used for basic authentication. If you wish to authenticate against a different domain, click the Edit button and select a different default domain.

Basic authentication works across proxy servers and through firewalls. It is supported by essentially all browsers. Basic authentication allows for delegation from one computer to another, but only for a single hop (i.e., only to one other computer). If you need to access resources beyond the first hop, you will need to log on locally to each of the other computers in the call chain. This is possible, since the username and password are available to your application in clear text.

19.1.2.3 Digest authentication

Digest authentication is very similar to basic authentication, except that the credentials are encrypted and a hash is sent over the network to the server. It is a fairly secure method of authentication, although not as secure as basic authentication used with SSL, Windows integrated authentication, or certificate authentication. Like basic authentication, digest works through firewalls and proxy servers. Digest authentication does not support delegation (i.e., impersonated requests to remote machines).

Digest authentication works only with Internet Explorer 5.x and higher and .NET web services. It also requires that the web server is running on Windows 2000, XP or Server 2003, and that all users have Windows accounts stored in an Active Directory. Because of these requirements, digest authentication is generally limited to intranet applications.

When the user requests a resource that requires digest authentication, the browser presents the same credentials dialog box as with basic authentication. The username and password are combined with a server-specified string value and encrypted to a hash value. This hash value is sent over the network. Since the server knows the string used to create the hash, it is able to decrypt the hash and extract the username and password. These are compared with the user accounts to determine if the user is authenticated, and if so, if the user has permission to access the requested resource.

To set the authentication method to Digest, refer back to Figure 19-2. Uncheck "Anonymous access," "Basic authentication," and "Integrated Windows authentication," if any of them are checked. Then check "Digest authentication." Note that the Digest authentication checkbox will not be available if the machine is not connected to a domain.

In addition, to configure ASP.NET you must include the following section in the relevant web.config configuration file:

<configuration>    <system.web>       <authentication mode="Windows" />    </system.web> </configuration>

In order for a user to be able to use digest authentication, the user account must be set to store the password using reversible encryption. To do this, go to the management console for Active Directory Users and Computers. Open the domain you want to administer and double-click on the user name that you want to use digest authentication. On the Account Options tab, select "Store password using reversible encryption."

19.1.2.4 Integrated Windows authentication

Integrated Windows authentication uses the current user's credentials presented at the time they logged into Windows. A dialog box is never presented to the user to gather credentials unless the Windows logon credentials are not adequate for a requested resource.

Integrated Windows authentication comprises two different types of authentication: NTLM (NT LAN Manager) challenge/response, and Kerberos. NTLM is the protocol used in Windows NT, Windows 2000 work groups, and environments with mixed NT and 2000 domains. If the environment is a pure Windows 2000 or Windows XP Active Directory domain, then NTLM is automatically disabled and the authentication protocol switches to Kerberos.

Kerberos is named after the three-headed, dragon-tailed dog (Cerberus) who guarded the entrance to Hades in Greek mythology.

Integrated Windows authentication works particularly well in intranet environments, where all the users will already have Windows domain accounts and presumably all users will be using IE 3.01 or later. It is very secure, since the encrypted password is not sent over the network. Note that Integrated Windows authentication does not work through a proxy server. NTLM does not support delegation, although Kerberos does.

Integrated Windows authentication does not require any login dialog boxes. Not only is this more convenient for the user, but it is well suited to automated applications, such as those using web services.

To set the authentication method to Integrated Windows authentication, refer back to Figure 19-2. Uncheck "Anonymous access," "Basic authentication," and "Digest authentication," if any of them are checked. Then check "Integrated Windows authentication."

In addition, to configure ASP.NET you must include the following section in the relevant web.config configuration file:

<configuration>    <system.web>       <authentication mode="Windows" />    </system.web> </configuration>

Kerberos is faster than NTLM, although neither is as fast as basic authentication or well-designed custom authentication methods. If you are anticipating a large number of concurrent users or are delegating security to back-end servers (e.g., SQL Server), then scalability may become an issue with Integrated Windows Authentication.

19.1.3 Passport Authentication

Passport is a centralized authentication service provided by Microsoft. It offers a single logon for all web sites that have registered with the Passport service, accepted the license agreement, paid the requisite fee, and installed the Passport SDK.

When a client makes a request to a Passport protected site, the server detects that the request does not contain a valid Passport ticket as part of the query string. The client is redirected to the Passport Logon Service along with encrypted parameters about the original request. The Passport Logon Service presents the client with a logon form, which the user fills out and posts back to the logon server using the SSL protocol. If the logon server authenticates the user, the request is redirected back to the original site, this time with the authentication ticket encrypted in the query string. When the original site receives this new request, it detects the authentication ticket and authenticates the request.

Subsequent requests to the same site are authenticated using the same authentication ticket. There are also provisions for expiring the authentication ticket and using the same ticket at other sites.

For sites that have implemented Passport and installed the Passport SDK, the PassportAuthenticationModule provides a wrapper around the SDK for ASP.NET applications.

Passport uses Triple-DES encryption to encrypt and decrypt the authentication key when passed as part of the query string. When a site registers with the Passport service, it is given a site-specific key that is used for this encryption and decryption.

It is not possible to use delegation if using Passport authentication.

To use Passport authentication, ASP.NET must be configured by including the following section in the relevant web.config configuration file:

<configuration>    <system.web>       <authentication mode="Passport" />    </system.web> </configuration>

19.1.4 Forms Authentication

Integrated Windows authentication offers many advantages to the developer who is deploying to an environment where all the clients are known to have user accounts in the requisite Windows domain or Active Directory and are also known to be using a recent version of Internet Explorer. However, in many web applications, one or both of these conditions will not be true. In these cases, forms authentication allows the developer to collect credentials from the client and authenticate them.

In forms authentication, a custom login form is presented to the unauthenticated user to gather credentials. This form does not necessarily authenticate the user itself, but rather submits the credentials, via form post, to application code that performs the authentication. The application code generally authenticates by comparing the credentials submitted with usernames and passwords contained in a data store of some sort. This data store can be a web.config configuration file, a relational database, an XML file, or even the Windows domain database or Active Directory.

The credentials submitted by the login form are sent unencrypted over the network, and so are vulnerable to interception by a skilled and malicious user of a network sniffer. A forms authentication scheme can be made fully secure by sending the credentials and all subsequent authenticated requests using the SSL protocol.

Once the client is authenticated, the server returns a small piece of data, called a cookie, back to the client. This authentication cookie is then passed from the client to the server on each subsequent request, which tells the server that this client has already been authenticated. If a request is made without a valid authentication cookie, then the user is automatically redirected to the login form, where credentials are once again gathered and authenticated.

19.1.4.1 Login form

To demonstrate forms authentication, you must first create a login form. At a minimum, this form must provide a means for the user to enter his username and password. It must also either provide the code to perform the authentication or call application code to do likewise.

Example 19-1 and Example 19-2 show the code for a simple login form using VB.NET and C#, respectively. Example 19-2 shows only the script block for the login form in C#, since the HTML portion is identical to that in Example 19-1.

Example 19-1. Simple login form in VB.NET, vbLoginForm-01.aspx
<%@ Page Language="vb" %> <script runat="server">    sub btn_Click(ByVal Sender as Object, _                  ByVal e as EventArgs)       if (txtUserName.Text = "Dan" and txtPassword.Text = "password") then          lblMessage.Text = "Authenticated: <br>" & txtUserName.Text & _                            "<br>" & txtPassword.Text          FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, _                                                    false)       else          lblMessage.Text = "Not Authenticated:<br>" & txtUserName.Text & _                            "<br>" & txtPassword.Text       end if    end sub </script> <html> <body>    <h1>Login Form</h1>    Please enter your credentials:    <br>    <form runat="server">       Username:&nbsp;&nbsp;       <asp:Textbox                     runat="server" />       <br>       Password:&nbsp;&nbsp;       <asp:Textbox                     TextMode="password"          runat="server" />       <br>       <br>       <asp:Button                    Text="Authenticate"          OnClick="btn_Click"          runat="server" />       <br>       <br>       <asp:Label                    runat="server" />    </form> </body> </html>
Example 19-2. Simple login form in C#, csLoginForm-01.aspx
<%@ Page Language="C#" %> <script runat="server">    void btn_Click(Object Source, EventArgs E)    {       if (txtUserName.Text=="Dan" && txtPassword.Text=="password")       {          lblMessage.Text = "Authenticated: <br>" + txtUserName.Text +                             "<br>" + txtPassword.Text;          FormsAuthentication.RedirectFromLoginPage(txtUserName.Text,                                                     false);       }       else       {          lblMessage.Text = "Not Authenticated: <br>" + txtUserName.Text +                            "<br>" + txtPassword.Text;       }    } </script>

When the login page from Example 19-1 or Example 19-2 is run in a browser and incorrect credentials are entered, you get the results shown in Figure 19-5.

Figure 19-5. Login form
figs/pan2_1905.gif

The HTML portion of the login form has an Authenticate button and two textboxes, one for the username and one for the password. Note that the password textbox has its TextMode attribute set to password, so that any characters entered will be displayed as asterisks. The HTML also includes a label for displaying the results of the authentication to the user.

When the Authenticate button is clicked, the btn_Click event handler is called. In this simple login scenario, a single username and password are hard-coded into the code. (Later in this chapter, you will see how to implement more flexible stores of usernames and passwords.) A simple if statement tests to see whether the username and password match. In VB.NET, this is done using:

if (txtUserName.Text = "Dan" and txtPassword.Text = "password") then

In C#, the code is:

if (txtUserName.Text=="Dan" && txtPassword.Text=="password")

Depending on the results of the test, the appropriate message is displayed in the label, along with the username and password (in clear text) entered in the textboxes.

The interesting action occurs in the highlighted line of code in Example 19-1 and Example 19-2, reproduced here (in VB.NET, without the line continuation character):

FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, false);

FormsAuthentication is a helper class in the System.Web.Security namespace that provides static or shared helper methods for managing forms authentication. (You will see more of these helper methods throughout this section.) The static RedirectFromLoginPage method first generates and places an authentication cookie on the client, then redirects the client browser back to the page which made the original request.

The first parameter in RedirectFromLoginPage is a text string that contains the username associated with the cookie. It is not necessary for this username to be an account name; it is used only for identification of the cookie itself.

The second parameter in RedirectFromLoginPage is a Boolean that specifies whether the cookie is persistent or not. A persistent cookie is one that is saved across browser sessions. If a persistent cookie is set, the user will not have to log in again on subsequent visits.

Obviously, hard-coding usernames and passwords into if statements in your code is a fairly limited authentication scheme. It would be much more useful if you could do some sort of lookup in a relational database, such as SQL Server, or in an XML data store. This could be accomplished with code based on that shown in Example 19-3 (in C#).

Example 19-3. Authenticating users from an external store
if (CheckCredentials(txtUserName.Text, txtPassword.Text) ) {    //  Do stuff if authenticated } else {    //  Do stuff if not authenticated } private bool CheckCredentials(string username, string password) {    //  Do a database or XML lookup to see if the username and     //  password are valid. ...//  If valid, then return true, otherwise return false. }

Here is the corresponding code in VB .NET:

if CheckCredentials(txtUserName.Text, txtPassword.Text) then    '  Do stuff if authenticated else    '  Do stuff if notauthenticated end if private function CheckCredentials(username as string, _   password as string) as Boolean    '  Do a database or XML lookup to see if the username and     '  password are valid.    '  If valid, then return true, otherwise return false. end function

In Example 19-3, a private method is created called CheckCredentials, which returns a Boolean. This method accesses an external store of usernames and passwords. This external store could be a relational database, an XML file, or even the Windows domain database or Active Directory. The point is that this method will do the actual work of authenticating the credentials passed in. If the credentials check out OK, the method returns true. If the credentials do not pass muster, the method returns false.

19.1.4.2 Configuring IIS

To implement forms authentication, IIS must be properly configured. This is done in the Authentication Methods dialog box shown in Figure 19-2. Depending upon whether you right-clicked on the default web site in the management console or in a specific virtual directory, the Authentication Methods dialog box will apply either to the entire server or to a specific web application.

Referring to Figure 19-2, uncheck all three checkboxes under "Authenticated access." That will disable integrated windows authentication.

Check the checkbox for "Anonymous access." That will tell IIS to allow any request to pass through IIS and be handled by ASP.NET. Your login form will pick it up from there, once all the pieces are in place.

19.1.4.3 Configuring ASP.NET

The final piece to setting up forms authentication is to properly configure ASP.NET. This is done using the appropriate instance of the web.config configuration file.

Remember that the effect of the configuration files in ASP.NET is hierarchical, in that a specific instance of web.config applies to its own directory and all subdirectories below it. If a subdirectory contains its own instance of web.config, any settings it contains will override its parent's settings and will apply to its directory and all its child subdirectories. (For a complete discussion of ASP.NET configuration files, see Chapter 20.)

To configure an entire web application, place the configuration settings in the instance of web.config in the application virtual root directory.

To configure ASP.NET to use forms authentication, edit the instance of web.config in the application virtual root directory to contain the code shown in Example 19-4.

Example 19-4. web.config entry for forms authentication
<configuration>    <system.web>       <authentication mode = "Forms">          <forms name="ProgAspNetCookie" loginUrl="csLoginForm.aspx" />       </authentication>       <authorization>          <deny users="?" />       </authorization>    </system.web> </configuration>

In the <authentication> section, the mode is set to Forms. This tells ASP.NET to use forms authentication.

Within that section is a <forms> tag. This contains the name of the authentication cookie to be placed on the client machine. In this example, the name of the cookie will be ProgAspNetCookie. If no name is provided, the default name is .ASPXAUTH.

The next attribute within the <forms> tag is loginUrl. (Note the casing of loginUrl. Remember that web.config files are case sensitive.) This contains the URL of the login form to be redirected to if an unauthenticated request is received by IIS.

The <forms> tag has three other attributes, which are as follows:

protection

Specifies whether the application should use data validation, data encryption, neither, or both to protect the cookie when it is passed between the server and the client. The default value is All, which specifies both. None specifies neither, Encryption specifies encryption only (using Triple-DES), and Validation specifies validation only.

Using a value of None is the weakest form of security a forms authentication scheme can have. It is not recommended, except for sites that do not have stringent security requirements, such as personalization. It is, however, the least resource-intensive way to implement personalization, and will scale better than the other methods.

timeout

Specifies the integer number of minutes before the authentication cookie expires. The default is 30. Whenever a new request is received for the cookie, the clock is reset. If a cookie is persistent, it never expires.

path

Specifies the path for cookies issued by the application. The default value is a backslash (/). Note that most browsers are case sensitive and will not return a cookie if there is a path/case mismatch.

The <authorization> section shown in Example 19-4 will be described in detail later in this chapter. For now, it is sufficient to know that it denies authorization to all anonymous users (i.e., all users who have not been authenticated).

19.1.4.4 Authenticating against web.config

The sample shown in Example 19-1 and Example 19-2 authenticate against a username and password hard-coded into the application code. Example 19-3 shows how to authenticate against an external data store. A third option is to authenticate against names stored in web.config. This is done by adding a <credentials> section within the <forms> section of web.config.

A typical <credentials> section is shown highlighted in Example 19-5.

Example 19-5. web.config entry for <credentials> section
<authentication mode = "Forms">    <forms name="ProgAspNetCookie" loginUrl="csLoginForm.aspx" >       <credentials passwordFormat="Clear">          <user name="Tom"   password="mot" />          <user name="Dick"  password="kcid" />          <user name="Harry" password="yrrah" />       </credentials >    </forms> </authentication> <authorization>    <deny users="?" /> </authorization>

Other than the lines highlighted in Example 19-5, this listing is identical to that in Example 19-4. (The <authorization> section will be described later in this chapter.)

The <credentials> tag has a single attribute, passwordFormat. This specifies the hash, or encryption, format for storing passwords. The legal values are Clear, MD5, and SHA1. The latter two are well-known hashing algorithms that are supported by most browsers.

To use the MD5 or SHA1 hash formats, the password strings actually entered into the web.config file must be hashed in the appropriate format. To get the string containing the hashed password, use the HashPasswordForStoringInConfigFile method of the FormsAuthentication class.

Within the <credentials> section, there are multiple <user> tags. Each specifies a username and associated password.

To fully implement authentication against web.config, you will need to modify the login form shown in Example 19-1 and Example 19-2, as shown in Example 19-6 and Example 19-7 for VB.NET and C#, respectively. Only the script blocks are shown in either language, since the HTML is unchanged. The highlighted lines are changed from Example 19-1 and Example 19-2.

Example 19-6. Login form authenticating against web.config in VB.NET, vbLoginForm-02.aspx
<%@ Page Language="vb" %> <script runat="server">    sub btn_Click(ByVal Sender as Object, _                  ByVal e as EventArgs)       if FormsAuthentication.Authenticate(txtUserName.Text, _                                           txtPassword.Text) then          FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, _                                                    false)       else          lblMessage.Text = "Not Authenticated:<br>" & txtUserName.Text & _                            "<br>" & txtPassword.Text       end if    end sub </script>
Example 19-7. Login form authenticating against web.config in C#, csLoginForm-02.aspx
<%@ Page Language="C#" %> <script runat="server">    void btn_Click(Object Source, EventArgs E)    {       if (FormsAuthentication.Authenticate(txtUserName.Text,                                            txtPassword.Text))       {          FormsAuthentication.RedirectFromLoginPage(txtUserName.Text,                                                     false);       }       else       {          lblMessage.Text = "Not Authenticated: <br>" + txtUserName.Text +                            "<br>" + txtPassword.Text;       }    } </script>

The login form shown in Example 19-6 and 19-7 uses the Authenticate method of the FormsAuthentication class. This static or shared method takes two parameters: username and password. These credentials are compared against the users listed in the <credentials> section of web.config. If the credentials authenticate, then the Authenticate method returns true; otherwise, it returns false.

Notice that the lines of code from Example 19-1 and Example 19-2 that display a message on successful authentication have been removed from Example 19-6 and Example 19-7, since they will never actually be seen. If the request is authenticated, the user will immediately be redirected back to the originating form. That message was useful primarily when originally developing the login form.

19.1.4.5 Authenticating with redirect to a specified page

All the forms authentication samples shown so far have used the RedirectFromLoginPage method of the FormsAuthentication class. This method creates the authentication cookie, then redirects the client back to the page that made the original unauthenticated request.

It is also possible to create the authentication cookie without an automatic redirection back to the originating page. This would be useful if you wanted to control where the client is redirected to.

To accomplish this, use the static SetAuthCookie method of the FormsAuthentication class. This method creates an authentication cookie and attaches it to the outgoing response. However, there is no automatic redirect. Instead, your code must perform the redirect explicitly.

Consider the script block shown for VB.NET and C# in Example 19-8 and Example 19-9, respectively. It is identical to the code in Example 19-6 and Example 19-7 except for the highlighted lines of code.

Example 19-8. Login form using SetAuthCookie in VB.NET
<%@ Page Language="vb" %> <script runat="server">    sub btn_Click(ByVal Sender as Object, _                  ByVal e as EventArgs)       if FormsAuthentication.Authenticate(txtUserName.Text, _                                           txtPassword.Text) then          FormsAuthentication.SetAuthCookie(txtUserName.Text, _                                            false)          Response.redirect("default.aspx")       else          lblMessage.Text = "Not Authenticated:<br>" & txtUserName.Text & _                            "<br>" & txtPassword.Text       end if    end sub </script>
Example 19-9. Login form using SetAuthCookie in C#
<%@ Page Language="c#" %> <script runat="server">    void btn_Click(Object Source, EventArgs E)    {       if (FormsAuthentication.Authenticate(txtUserName.Text,                                            txtPassword.Text))       {          FormsAuthentication.SetAuthCookie(txtUserName.Text,                                             false);          Response.Redirect("default.aspx");       }       else       {          lblMessage.Text = "Not Authenticated: <br>" + txtUserName.Text +                            "<br>" + txtPassword.Text;       }    } </script>

In Example 19-8 and Example 19-9, the SetAuthCookie method creates the authentication cookie for the client, using the same parameters as the RedirectFromLoginPage method. The first parameter is the username of the client, and the second parameter is a Boolean that specifies whether the cookie is persistent.

Rather than redirecting the client back to the originating page, the code in Example 19-8 and Example 19-9 redirects the client to the specified page, here called default.aspx.

In this example, the redirect page is hard-wired. It is easy to imagine modifying the CheckCredentials method described in Example 19-3 so that, in addition to authenticating the credentials, the method also sets a member variable containing a category to which the user belongs. Then your code could redirect to whichever page was appropriate for each category.

If you want your code to do the redirect, as in Example 19-8 and Example 19-9, but you want to redirect to the original requesting page, similar to the functionality provided by RedirectFromLoginPage, then you can use the static GetRedirectUrl method of the FormsAuthentication class. This method returns a string containing the originating URL. It takes the same parameters as RedirectFromLoginPage, and sets the authentication cookie similarly. You could replace the highlighted lines of code in Example 19-8 with the following code to redirect back to the originating page:

dim strUrl as string strUrl = FormsAuthentication.GetRedirectUrl(txtUserName.Text, _                                            false) Response.redirect(strUrl)
19.1.4.6 Getting the authentication cookie

Sometimes it is useful to get the authentication cookie but not immediately send it back to the client. This would be the case if you wanted to add information to the cookie or modify the information it already contains. The static GetAuthCookie method of the FormsAuthentication class serves this purpose.

Consider the code in Example 19-10 for VB.NET and Example 19-11 for C#, which modify the code shown in Example 19-8 and Example 19-9, respectively. It creates the authentication cookie, modifies it, then does the redirect.

Example 19-10. Login form using GetAuthCookie in VB.NET, vbLoginForm-03.aspx
<%@ Page Language="vb" %> <script runat="server">    sub btn_Click(ByVal Sender as Object, _                  ByVal e as EventArgs)       if FormsAuthentication.Authenticate(txtUserName.Text, _                                           txtPassword.Text) then          dim myCookie as HttpCookie          myCookie = FormsAuthentication.GetAuthCookie(txtUserName.Text, _                                                       false)          myCookie.Expires = DateTime.Now.AddHours(24)          Response.Cookies.Add(myCookie)          Response.redirect("default.aspx")       else          lblMessage.Text = "Not Authenticated:<br>" & txtUserName.Text & _                            "<br>" & txtPassword.Text       end if    end sub </script>
Example 19-11. Login form using GetAuthCookie in C#, csLoginForm-03.aspx
<%@ Page Language="c#" %> <script runat="server">    void btn_Click(Object Source, EventArgs E)    {       if (FormsAuthentication.Authenticate(txtUserName.Text,                                            txtPassword.Text))       {          HttpCookie myCookie =              FormsAuthentication.GetAuthCookie(txtUserName.Text,                                                false);          myCookie.Expires = DateTime.Now.AddHours(24);          Response.Cookies.Add(myCookie);          Response.Redirect("Default.aspx");       }       else       {          lblMessage.Text = "Not Authenticated: <br>" + txtUserName.Text +                            "<br>" + txtPassword.Text;       }    } </script>

In Example 19-10 and Example 19-11, if the credentials are authenticated, a cookie variable, myCookie, is instantiated. The GetAuthCookie method is called, which returns an object of type HttpCookie. This is assigned to myCookie. The Expires property of the cookie is modified to add 24 hours to the expiration date and time. Finally, the cookie myCookie is added to the Cookies collection of the HttpResponse object. If this last step is not performed, then the cookie will not be set on the client's computer and the request will not be authenticated. Once the cookie is set, the redirect can occur, as before.

19.1.4.7 Logging out

If a cookie is not persistent, it will expire when its expiration period ends. If it is persistent, it will never expire. It is possible to force an authentication cookie to expire immediately by calling the static SignOut method of the FormsAuthentication class.

The code in Example 19-12 shows a simple page that contains only a button that removes the authentication cookie, effectively logging the user out of the application. The code in Example 19-12 is in VB.NET; the C# code within the <script> tag is very similar, as shown in Example 19-13:

Example 19-12. Logout form in VB.NET, vbLogout.aspx
<%@ Page Language="vb" %> <script runat="server">    sub btn_Click(ByVal Sender as Object, _                  ByVal e as EventArgs)       FormsAuthentication.SignOut(  )    end sub </script> <html> <body>    <h1>Logout Form</h1>    <br>    <form runat="server">         <asp:Button                    Text="Log Out"          OnClick="btn_Click"          runat="server" />    </form> </body> </html>
Example 19-13. Logout form in C#, csLogout.aspx
<%@ Page Language="C#" %> <script runat="server">    void btn_Click(Object sender,                  EventArgs e)    {       FormsAuthentication.SignOut(  );    } </script>

The page coded in Example 19-12 consists of a single button, labeled "Log Out." Clicking on this button calls the SignOut method. You can verify that this works by calling any page in the virtual directory in your browser, logging in, then calling any other page to verify that you do not need to log in with subsequent pages once you are logged in. Then call vbLogoutForm.aspx in your browser and click the Log Out button. Now call one of the other pages again. You will be redirected to the login form, since there is no longer a valid authentication cookie on your client machine.

19.1.5 Certificate Authentication

Certificates are digital keys that are installed on a computer. Certificates can be installed on either the server or the client. Certificates are generally issued by third parties, which manage the logistics of issuing and maintaining the certificates and guarantee their validity. When a request is made to a server using certificate authentication, the client certificate is passed to the server as credentials, and the server certificate is passed back to the client to verify the identity of the server. Mutual authentication can take place.

Certificate authentication is seamless: it does not present any login dialog boxes or forms, and there is no need for the client to programmatically provide the username or password. The server and the client authenticate each other automatically, with no user interaction. This not only makes it much easier for the client, but it is also ideal for automated scenarios, such as those using web services.

Certificate authentication is very secure. The data contained in the certificate is encrypted using public key encryption technology. While it is beyond the scope of this book to discuss cryptography details and the merits of public key encryption, suffice it to say that it is a widely used and very safe means of passing encrypted data over the Internet.

You can create your own certificates conforming to the X.509 standard for authentication and encryption for testing purposes. This is done using MakeCert.exe, a command-line certificate creation tool included with the .NET Framework. For a complete description of MakeCert.exe, including all the command-line arguments, see the SDK documentation that comes with .NET.

Client certificates can be mapped to user accounts in either a Windows domain or Active Directory. This mapping can be either one-to-one, where a certificate is mapped to a single user, or many-to-one, where a single certificate is mapped to many users. With a many-to-one mapping, a single certificate can be assigned to a company, and all the users from within that company can authenticate using the same certificate.

There is a cost associated with issuing, installing, and managing certificates. There is typically a fee paid to the third-party issuer of the certificates. There is also the cost of the effort by the developers and/or system administrators to implement certificate authorization on both the server and all client machines. Client certificates must be physically deployed on each client machine. This deployment can be performed over the web or via installation software on CD, but it must be performed for each client. This limits deployment of certificate authentication to closed systems, such as intranets or B2B relationships.



Programming ASP. NET
Programming ASP.NET 3.5
ISBN: 0596529562
EAN: 2147483647
Year: 2003
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net