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.
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.
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
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:
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
<web-resource-name>Hello with BASIC protection</web-resource-name>
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.
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.
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
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 the
BASIC keyword has been replaced by
<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
<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)
<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><input type="submit" value="Login" /></p>
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)
<p>Sorry, you can't come in.</p>
<form action='<%=response.encodeURL("login.jsp")%>' method="post">
<input type="submit" value="Try Again" />
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.