Authentication

 

Microsoft Corporation
October 2003

Applies to:
    Microsoft® ASP.NET
    Microsoft Internet Information Services (IIS)
    Microsoft Visual Studio® .NET
    Microsoft Passport
    Java Server Pages (JSP)

Summary: Learn about authentication schemes available to ASP.NET applications and how to implement them. This article includes brief examples of authentication schemes also available to JSP. (13 printed pages)

Contents

Introduction
Authentication in JSP
Authentication in CodeNotes
Conversion With the JLCA
Authentication in ASP.NET
Summary

Introduction

Authentication is a process of proving that someone is who they say they are. In Web applications, authentication generally consists of two parts: querying for credentials (usually by some interface that requests a login name and password) and verifying those credentials against some source (such as a database). Most Web applications created or worked with using servlets and JSP will have some kind of authentication process to determine who is accessing the application. Bare in mind that authentication is not the same thing as authorization, which is the process of determining what parts of a Web site or Web application a user can access after his or her identity has been authenticated.

This article will provide brief examples of some familiar JSP-based authentication schemes. Unfortunately, because authentication is tied into the Web.xml (Java) and Web.config (Microsoft® ASP.NET) files, the Java Language Conversion Assistant (JLCA) will not directly convert authentication rules. We will look briefly at what the JLCA does and how to finish the conversion process. Finally, we will discuss the various types of authentication available to ASP.NET applications, and how to implement these schemes so that the authentication process on a new ASP.NET application will be as close as possible to the process in a JSP application.

Authentication in JSP

There are actually four different ways of authenticating users using servlets and JSP. These are:

  • Basic authentication, which is defined in the HTTP/1.1 specification. When a user attempts to access a JSP page, the system will request a user name and password (using a built-in interface that depends on the Web browser) and will allow several (usually three) attempts to supply correct credentials before providing an error page (usually an HTTP 401 Unauthorized error).
  • Form-based authentication, which is similar to basic authentication except that you can create your own login interface by using HTML. This is often more useful than basic authentication because you can create login interfaces that require something other than, or in addition to, the traditional user name and password (such as an e-mail address or digits of a telephone number).
  • Digest authentication is also similar to basic authentication, except that passwords are encrypted using a hash formula. This makes digest authentication more secure than basic authentication, as only the password's hash value is transmitted over HTTP. However, digest authentication is still rarely used, simply because there are better and more complex ways of providing security (such as using HTTPS and SSL).
  • Client certificate authentication requires that each client accessing the resource has a certificate that it sends to authenticate itself. This type of authentication requires the SSL (Secure Sockets Layer) protocol.

Only the first two of these authentication methods are commonly used in JSP applications. An example of each follows.

Basic Authentication

Assuming you have a JSP application you want to secure, you can create a basic authentication scheme that will cause a user's browser to present him or her with a dialog requesting a user name and password each time he or she attempts to access a page in that application in a new session.

Login configuration

To indicate that your server should be using basic authentication, you need to add a<login-config>element to your Web.xml file (if this element does not already exist). Web.xml is usually located in the WEB-INF directory on your server. The<login-config>element should look something like Listing 1.

Listing 1. A <login-config> element for basic authentication

<login-config>
   <auth-method>BASIC</auth-method>
   <realm-name>CodeNotes Examples</realm-name>
</login-config>

You would want to change the realm name to something more suited to your own application. In addition, notice how we indicate that basic authentication will be used using the keyword BASIC. The other three methods of authentication use similar capitalized keywords: FORM, DIGEST, and CLIENT-CERT.

Security constraints

You then need to add a security constraint to Web.xml for each page that requires authentication. A<security-constraint>element looks something like Listing 2.

Listing 2. A <security-constraint> element for basic authentication

<security-constraint>
   <web-resource-collection>
   <web-resource-name>Hello with BASIC protection</web-resource-name>
   <url-pattern>/HelloBasic.jsp</url-pattern>
   </web-resource-collection>
   <auth-constraint>
   <role-name>codenotes</role-name>
   </auth-constraint>
</security-constraint>

As you can see, a security constraint consists of two parts: a Web resource collection, which names the resource and provides its URL so that the server knows that this particular page requires authentication; and an authorization constraint, that allows you to indicate what roles (that is, groups of users) are allowed to access the page.

User names and passwords

The location and method in which user names and passwords are stored depends on the servlet container you use to provide access to your servlets and JSP pages. For example, the Tomcat servlet contains stored user names and passwords in an unencrypted XML file named Tomcat-users.xml (located in Tomcats conf folder). Each user is stored in a separate<user>element, which looks something like Listing 3.

Listing 3. A <user> element in Tomcat-users.xml

<user name=craig password=secret roles=codenotes />

Each user has a user name, a password and a list of roles, or groups, of which he or she is a member. The roles attribute can contain a comma-separated list of roles so that users can be members of more than one role. Remember that we indicate roles that can access our JSP pages, and not specific users.

Other servlet containers or Web servers will have their own methods of storing user names and passwords. Having developed JSP applications in the past, you will probably be familiar with your own server; if not, you should see its documentation to determine where this information is kept.

Accessing the page

If you completed the steps above, opening the page HelloBasic.jsp in Microsoft® Internet Explorer will cause a dialog box to appear in your browser. You must provide a valid user name and password in order to access the page.

Notice that the realm name we specified in the<login-config>element is used as the subtitle for this dialog box. Remember also that the appearance of this dialog box will be different if you are using a browser other than Internet Explorer; the basic structure and functionality of the box, however, will be the same.

Form-based Authentication

The basic steps of adding form-based authentication are very similar to those for basic authentication, except that there is the additional work of designing a login page containing the form that will allow a user self-authentication.

Login configuration

As with basic authentication, you need to add a<login-config>element to Web.xml. This time, however, the element is a little more complicated because you need to tell the servlet container where to find the login page and, optionally, where to find the error page that will be displayed if the login is unsuccessful.

Listing 4 shows a<login-config>element for a JSP application using form-based authentication.

Listing 4. A<login-config>element for forms-based authentication

<login-config>
   <auth-method>FORM</auth-method>
   <form-login-config>
   <form-login-page>/login.jsp</form-login-page>
   <form-error-page>/error.jsp</form-error-page>
   </form-login-config>
</login-config>

Notice that the<realm-name>element has been replaced by a<form-login-config>element, in which we specify the login and error pages. Also notice that theBASICkeyword has been replaced by FORM.

Security constraints

The<security-constraint>element can be exactly the same as it was for basic authentication. No special additions are required to make authentication form-based. The only difference that you will see in the example at the end of this section is that the page that requires authentication is called HelloForm.jsp rather than HelloBasic.jsp.

Designing a login form

Login forms require the use of special keywords for the actions or names of the<form>and<input>elements used for authentication. These keywords let the server know that these particular parts of the input should be checked against the stored user info. A simple login page might look like Listing 5:

Listing 5. A simple login page (login.jsp)

<html>
   <head><title>Login</title></head>
   <body>
      <form action="j_security_check" method="post">
         <p>Enter your user name and password here.</p>
         <p>User name: <input type="text" name="j_username" /></p>
         <p>Password: <input type="password" name="j_password" />
         </p>
         <p><input type="submit" value="Login" /></p>
      </form>
   </body>
</html>

All this page does is provide entry fields for a user name and password and a submit button that submits the field data. However, take note of the fact that the action for the form is j_security_check, and that the names of the user name and password<input>elements are j_username and j_password, respectively. These keywords are all defined in the servlet specification and must be used in order for this form to be treated as a login page.

Designing an error page

Forms-based authentication allows designed, custom error pages. Listing 6 shows an example of a simple error page that informs the user that their credentials were not valid, and provides a button to return to the login page and try again.

Listing 6. A simple error page (error.jsp)

<html>
   <head><title>Error</title></head>
   <body>
   <p>Sorry, you can't come in.</p>
   <form action='<%=response.encodeURL("login.jsp")%>' method="post">
      <input type="submit" value="Try Again" />
   </form>
   </body>
</html>

Note the use of the encodeURL() method. This method encodes the given URL with a session ID if one exists, or returns just the URL if one does not exist. You can find information on this and the other request and response methods in the J2EE API documentation.

Accessing the page

If you completed the steps above, opening HelloForm.jsp in Internet Explorer will open a page. Valid credentials will open HelloForm.jsp. Invalid credentials will open error.jsp.

Authentication in CodeNotes

The only area in the CodeNotes Web site that requires authentication is posting to forums. In the JSP version, the CodeNotes Web site uses a simple forms-based authentication, but does not directly tie into the authentication schemes defined in the J2EE specification. Although this situation is not ideal, it worked well for our particular needs. A more common case would be to require a login for any action on the Web site. For those scenarios, one of the above authorization schemes would be more appropriate.

Conversion with the JLCA

Because authorization is defined in the Web.xml file, which is not converted by the JLCA, the authorization scheme you use in your JSP application will not be directly transferred to an ASP.NET equivalent. Fortunately, re-implementing your scheme is as simple as changing some configuration settings. In a simplified form, the relationships between JSP and ASP.NET authentication are as follows:

Table 1. Authentication mappings between JSP and ASP.NET

JSP ASP.NET Conversion
Basic Basic/Microsoft Windows® Update ASP.NET config file
Form Form JLCA converts form

Update ASP.NET config file

Update database access

Update error page links

Digest N/A Use alternate method
Certificate N/A Can re-work into Form based
  Microsoft Passport No conversion required

As you will see in the remainder of this article, the ASP.NET basic and form authentication styles are very similar to the JSP equivalents.

Authentication in ASP.NET

Having read the previous section, you should have a good idea of the options available for authentication under JSP. Most likely, you have already used or at least encountered one or more of the JSP authentication schemes in your experience as a JSP developer. With those options in mind, we will now discuss authentication procedures in ASP.NET, including what options are available, differences and similarities between ASP.NET authentication and JSP authentication, and several different ways of authenticating users under ASP.NET.

In this topic, we will discuss four forms of authentication, each of which has its advantages and disadvantages:

  • Windows authentication, which is controlled and executed by IIS and is useful mainly for intranet Web applications.
  • Basic authentication, which is an insecure protocol controlled and executed by IIS but can be used by Internet applications that do not require security or use additional security methods such as SSL.
  • Form-based authentication, which is extremely similar to the form-based authentication we discussed in the JSP Authentication section at the beginning of this document. We will attempt to use these similarities to make learning ASP.NET authentication pages easier.
  • Passport authentication, which uses Microsoft's Passport Web service to authenticate the user.

Windows Authentication

Windows authentication, also called Integrated Windows authentication, uses Windows operating system accounts to verify a user's credentials. This means that the user must either be logged in to the domain on which the server is running (in which case they will not be queried for credentials), or must log in to the domain when they try to access a protected page. This authentication scheme is part of IIS, and must be configured and executed by IIS; it is entirely separate from ASP.NET and is not, as such, an ASP.NET authentication mechanism.

Different Windows operating systems use different authorities to determine whether credentials are valid. In Microsoft Windows NT® version 4, user name and password information was stored in the Security Accounts Manager (SAM), and validation was performed by the NT LAN Manager (NTLM); however, since IIS 5.0 is required for ASP.NET and works only under Windows 2000 or later, you probably will not encounter these entities. In Windows 2000 or Windows XP, user name and password information is stored in the Microsoft Active Directory® database, and validation is performed by a protocol called Kerberos. Regardless of your operating system, most of the work of validating credentials is done behind the scenes, and configuring authentication is only a matter of adjusting some values in an IIS dialog window.

To configure Integrated Windows authentication, you will need to use the Internet Service Manager (the configuration client for IIS). In Windows 2000, this application can be found on the Start menu under Programs, Administrative Tools, Internet Services Manager. In Windows XP, you will need to open the Control Panel, select Administrative Tools, and then select Internet Information Services.

Find the virtual directory for the application to which you want to add authentication. Right-click the directory name, click Properties, and then click the Directory Security tab. Click the Edit button under Anonymous access and authentication control. This will open the Authentication Methods window in which you can configure the IIS authentication rules.

To turn on Windows Authentication, simply deselect the Anonymous access checkbox. This tells IIS that anonymous access is not allowed to this Web location, and therefore credentials are necessary.

Note that if you try opening the page whose authorization settings you just changed in a browser, it will probably let you access the page without having to enter a user name or password. This is because, presumably, you are already logged in to the same domain as the Web application, and therefore it already knows who you are. Users not logged in to the domain will have to log in at access time; they will have three chances, and IIS will return an Access Denied error page if all three fail.

One major caveat to this authentication scheme is that users must be able to log on to the domain on which the server is running. This means that Integrated Windows authentication is only suitable for intranet Web applications, as remote users cannot log on to your network. However, because this protocol does not send passwords over the network, it is extremely secure; therefore, if you are running intranet Web applications, this type of authentication is highly preferable to other less-secure modes such as ASP.NET basic or form-based authentication.

Basic Authentication

ASP.NET basic authentication is very similar to basic authentication under JSP. If a Web resource requires basic authentication, browsers pointed at that resource will open a browser-specific login dialog that requires the user to enter a name and password. Users of basic authentication do not require accounts on the server domain, as they did with Windows authentication. As with JSP basic (and form-based) authentication, however, passwords are sent in base64 encoding over HTTP and are not encrypted in any way.

Configuration

Like Integrated Windows authentication, basic authentication is performed by IIS and therefore needs to be configured in IIS. Open the Internet Services Manager and go to the Authentication Methods dialog for your virtual directory, as detailed in the previous section. You want to disable Anonymous access and Integrated Windows authentication, and enable basic authentication.

Note that we provide a default domain name and realm for our application. The domain name should match the domain name of your Web service (that is, the one that has permission to access the application). As in JSP, the realm name will simply be used to subtitle the Login dialog box when it appears. Also note that when you select basic authentication, IIS will warn you that your password will be sent unencrypted over the network and that this is a major security risk. As previously mentioned, basic authentication is completely insecure and requires an additional protocol such as SSL to make it safe.

User names and passwords

When using basic authentication, user names and passwords are stored as user accounts on the system on which the server is running. This means that you need to use the Windows utility for adding user accounts; only valid Windows accounts can be used to log in using basic authentication. The User Accounts setup and wizard can be found in the Windows Control Panel. Adding a new user to the system is relatively self-explanatory.

Security configuration in ASP.NET

You may recall that in JSP, login and security configuration is done in an XML document called Web.xml. Similarly, every ASP.NET application has an XML file called Web.config that is automatically generated for it upon creation. You can edit Web.config in any text editor such as Notepad, or you can open it in Microsoft Visual Studio® .NET by double-clicking it in the Solution Explorer at the right side of the screen.

Open Web.config, and scroll down until you see an element that looks something like this:

<authentication mode=Windows />

It is inside this element where all ASP.NET authentication settings should be placed. For basic authentication, however, you do not need to modify any settings in Web.config. Later, when we discuss form-based authentication, we will be making many changes to this configuration file. For now, simply note that the Windows mode indicates that IIS will handle the authentication process for this application; Windows mode is used for both basic authentication and Integrated Windows authentication.

Accessing the page

If you set up IIS according to the instructions above, you should now be able to open your application in a Web browser and see a login dialog.

Notice that this dialog is exactly the same as the one produced by our JSP basic authentication example. This is because the dialog box style is specific to the browser (in this case Internet Explorer) and not to the programming language used to develop the application or the server on which it runs.

Basic authentication under Windows, by default, will allow three attempts at a correct user name and password combination. If all three fail, it will send an HTTP 401.2 Unauthorized error. Since basic authentication is performed by IIS and not by ASP.NET, you cannot create customized error pages since ASP.NET will never have a chance to see the request.

Form-based Authentication

Form-based authentication is similar to basic authentication, except that it allows you to define your own login and error pages. In addition, it does not require the additional setup in IIS that basic authentication requires. Before starting the example in this section, you should go into IIS and change the authentication settings back to what they originally were (that is, allow anonymous access and Integrated Windows authentication, but not basic authentication).

Login configuration

In the section on basic authentication, we introduced the Web.config file. Recall that this file is generated for each Web application, and that it stores all of the configuration information about the application in XML format. In order to tell the application that we are using form-based authentication, we need to make some changes to the<authentication>element in Web.config.

Open your application project in Visual Studio .NET, double-click Web.config to open it, and scroll down to the<authentication>element. Modify it so that it looks like Listing 7.

Listing 7. <authentication> element for forms-based authentication

<authentication mode="Forms">
   <forms name="LoginForm" loginUrl="login.aspx" protection="All" />
</authentication>

The name and loginUrl attributes are self-explanatory. The protection element requires a little more explanation. When you use forms authentication, ASP.NET looks for a Forms cookie on the browser that is accessing the Web application. If it does not find one, it forwards the browser to the specified login page. If it does find one, it assumes the browser has already logged in during this session (that is, it already knows who the user is) and proceeds directly to the requested page. The protection element indicates to what degree this cookie will be encrypted and validated for security. All is the highest and most reliable setting; others are available, and more information on them can be found on MSDN®.

Since we are not going to be using IIS authorization to control access to anonymous users, we also need to add an additional element to Web.config. The<authorization>element, shown in Listing 8, allows you to permit or deny particular users or groups of users to use the application. In the case of Listing 8, we are denying access to all anonymous users (the special character?represents anonymous users).

Listing 8. Denying anonymous users access

<authorization>
   <deny users=? />
</authorization>

We could also have added<deny>elements for specific user names, allowed access to some users and not others, and so on.

User names and passwords

For our purposes, the easiest way to store user names and passwords is in the Web.config XML file, right alongside the other authentication information. In reality, because user names and passwords are accessed programmatically in ASP.NET (as we will see shortly), you could easily retrieve them from a database or a customized XML file of your own design. In many cases such methods will be preferable (and possibly more similar to what you did with your JSP applications), so we will point out where and when such code should be added when we look at the ASP.NET code in just a moment.

For now, find the<authentication>element in Web.config again and add to it so that it looks like Listing 9.

Listing 9. Storing user name and password information in Web.config

<authentication mode="Forms">
   <forms name="LoginForm" loginUrl="login.aspx" protection="All" />
      <credentials passwordFormat="Clear">
         <user name="craig" password="secret"/>
      </credentials>
   </forms>
</authentication>

Using the<credentials>element, we have added one user to the list of potential users for this application. We will see in a moment how to check against the users in this list. For now, note the passwordFormat attribute; a value ofClearindicates that this password will be readable to humans (that is, unencoded). Additional values are available that will cause the password to be encrypted before being sent across the network.

Designing a login form

Unlike in our JSP example, we can take advantage of Visual Studio .NET and design the appearance of our ASP.NET login form using the forms designer, and place all important code in the CodeBehind file. This allows us to have a much better idea of what the form will look like while designing it, and also allows us to keep most of the C# code separate from the HTML page design.

We'll start by adding a new form to the project called Login.aspx. We can add some text fields and a button to this form to make it look similar to the form we created in our JSP example simply drag and drop the necessary components into the design window and arrange them.

Now, open the CodeBehind file for Login.aspx. Here we need to add code in two different places. First, we need to add the following using directive to the top of the page:

using System.Web.Security;

This namespace contains all the necessary classes for ASP.NET security.

We then need to add some code to verify the user name and password to the Click method corresponding to our login button. If your CodeBehind does not already contain a Button1_Click method, go back to the form editor and double-click the login button to create one. Inside Button1_Click, add code as shown in Listing 10.

Listing 10. Button1_Click code for forms-based authentication

private void Button1_Click(object sender, System.EventArgs e) {
   if (FormsAuthentication.Authenticate(TextBox1.Text, TextBox2.Text)) {
      FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, false);
   } else {
      Label1.Text = "Login failed. Please try again.";
   }
}

As you can see, this code uses two methods of the FormsAuthentication object, which resides in the System.Web.Security namespace.

The Authenticate() method receives two string parameters representing a user name and password and checks them against the list of valid credentials in Web.config. In this case, we are checking whether the values in our two fields match an existing set of credentials.

The RedirectFromLoginPage() method receives two parameters as well. The first is a user name, which is passed to the applications authorization policy. Basically, it will be used to determine what parts of the application this user has access to, and what parts are restricted. The second parameter is a boolean indicating whether or not the application should send the user a persistent cookie. Setting this to false forces the user to log in if he or she opens the same application in a new browser window; setting it to true allows them to continually use the page in multiple browser windows without having to log in each time.

Notice also that our authentication and resulting actions from valid and invalid credentials are completely programmatic in nature. This means that instead of checking against the Web.config file using the FormsAuthentication class, we could easily have matched the provided credentials against a user database or against a custom XML file. Storing user names and passwords is an easy way because it allows you to use built in forms authentication methods, but it is certainly not the only or best way.

In addition, we could easily have redirected the user to a custom error page if the credentials were invalid instead of simply changing a message on the same page, much as we did in the JSP examples earlier in this document.

Accessing the page

Having saved and compiled your project, you can now access it using a Web browser. Assuming our application is called HelloForms, we can test out the login page by pointing a browser at https://localhost/HelloForms/WebForm1.aspx. The browser will redirect to the login page.

Notice how similar this page looks to the login page for our forms-based JSP example. If you enter invalid credentials, the label at the top of the window will change to an error message. Valid credentials (for example,craigand secret) will allow you to continue on to WebForm1.aspx.

Passport Authentication

You can also use the Passport authentication system from within .NET. This system offers an independent authentication and authorization system as a single login. That is, you sign in to Passport once and allow passport to sign you in to any Web site or Web application that allows Passport authentication. For more information on Passport, and using Passport in ASP.NET applications, see the MSDN Library.

Summary

Authentication is the process of identifying an accessing user by using credentials such as a user name and password. Both JSP and ASP.NET have a variety of ways in which authentication procedures can be implemented in a Web application. If you are building Web applications using ASP.NET, authentication can be performed by IIS or by ASP.NET itself.

IIS authentication options include Integrated Windows authentication, which uses a built-in login application and requires that users be signed in to the domain on which the application is running; and basic authentication, which requires that users have an account on the server and also uses the built-in login form, but sends user names and passwords unencrypted over the network.

ASP.NET allows you to create customized Web forms for login screens in which you can programmatically decide how and where credentials are verified and what happens if they are and are not valid. This forms-based authentication is very similar to the JSP forms-based authentication, and is probably the most popular method of authentication for Web applications. Visual Studio .NET makes creating Web forms extremely simple, as you will probably never have to code any of the design features on your ASP.NET pages. ASP.NET also allows you to use Microsoft Passport authentication. This is similar to forms-based authentication, except that the login and verification of credentials is provided externally, by the Microsoft Passport Web service. In order to use Passport authentication on a production Web site, you must register with Microsoft Passport, which includes providing information about your business and Web applications as well as paying a registration fee.

The wide variety of options for authentication in ASP.NET allows you to select an authentication scheme that meets your needs, as well as your security and time constraints.

© Microsoft Corporation. All rights reserved.