Many books have been written about the wide ranging topic of computer security, including Java security. In this sample chapter, author David Geary discusses protecting web application resources with the authentication mechanisms described in the servlet specification.

This sample chapter is excerpted from Advanced JavaServer Pages, by David Geary.

Computer security used to be the domain of hackers and their antagonists, but
with the advent of the World Wide Web, it's become an issue for the rank
and file setting up shop on the net. Because of this growing awareness, software
developers today are far more likely to deal with security than were their
counterparts of the late 20th century.

Many books have been written about the wide ranging topic of computer
security, including Java security, and this chapter is a substitute for none of
them. This discussion is restricted to protecting web application resources with
the authentication mechanisms described in the servlet
specification.1

Servlet Authentication

Servlet authentication looks simple:

A user tries to access a protected resource, such as a JSP page.

If the user has been authenticated, the servlet container makes the
resource available; otherwise, the user is asked for a username and
password.

If the name and password cannot be authenticated, an error is displayed
and the user is given the opportunity to enter a new username and password.

The steps outlined above are simple, but vague. It's not apparent who
asks for a username and password, who does the authentication, how it's
performed, or even how the user is asked for a username and password. Those
steps are unspecified because the servlet specification leaves them up to
applications and servlet containers. This vagueness in the servlet specification
has an effect on portability; see "Portability" for more
information.

Principals and Roles

In security-speak, the user in the steps listed on page 251 is a
principal. Principals are named entities that can represent anything;
most often, they represent individuals or corporations.

Principals can fill one or more roles; for example, a customer could also be
an employee. Security constraints in WEB-INF/web.xml associate
roles with protected resources, like this:

Two security constraints are specified above that restrict access to
/page_1.jsp and /page_2.jsp to principals that are in roles
customer or employee, respectively.

Security constraints, like those listed above, associate resources with
roles. It's up to servlet containers or applications to associate roles
with principals; for example, with Tomcat, you edit a tomcat-users.xml
file that has entries like this:

Here, rwhite has a password of tomcat and can fill roles
customer or other; thus, rwhite can access
/page_1.jsp, but not /page_2.jsp according to the security
constraints listed above.

Other servlet containers provide different mechanisms for associating
principals with roles; for example, "Resin" illustrates how it's
done with Resin for basic authentication.

Table 9-1 lists HttpServletRequest methods that allow you to
retrieve information about principals and roles.

Table 9-1 HttpServletRequest Methods for Principals and Roles

Method

Description

Principal getUserPrincipal()

Returns a reference to a java.security.Principal

boolean isUserInRole(String)

Determines whether a user is in a role, specified by the string argument

String getRemoteUser()

Returns the username that was used for login

The servlet API does not provide corresponding setter methods
for the getter methods listed in Table 9-1; therefore, principals and roles can
only be set by servlet containers, meaning that applications cannot set them.
This can be a consideration if you implement programmatic
authenticationsee "Programmatic Authentication" for more
information.

Like the methods listed in Table 9-1, the servlet API does not
provide corresponding setter methods for those methods listed in Table 9-2. This
means that the authentication type and transport scheme can only be set by
servlet containers.

Declarative Authentication

Declarative authentication requires no programming because authentication is
declared with XML tags in a deployment descriptor and implemented by the
servlet container. Declarative authentication is attractive because it's
easy, but it's not as flexible as other approaches that require you to
write code.

At one end of the spectrum is, declarative authentication, with is 100%
servlet container implemented and 0% application code; at the other end is
programmatic authentication, with 0% servlet container and 100% application
code.

Most servlet containers provide access to the middle of that spectrum by
providing hooks so that you can replace their default authentication
mechanism.

Portability

The servlet specification leaves enough security details unspecified that
servlet containers must fill in the gaps with nonportable functionality. For
example, the servlet specification does not specify a default authentication
mechanism, so servlet containers implement their own; for example, Tomcat uses
an XML file to specify usernames and passwords, whereas Resin requires you to
implement an authenticator.

Because of nonportable security aspects of servlet containers and depending
upon your choice for authentication, you may need to write some nonportable
code, such as a Resin authenticator or a Tomcat realm, both of which are
discussed in "Customizing Authentication".

On the other hand, you can use declarative authentication to minimize any
code you have to write.

Types of Authentication

A servlet-based web application can choose from the following types of
authentication, from least secure to most:

Basic authentication

Form-based authentication

Digest authentication

SSL and client certificate authentication

All of the authentication mechanisms listed above are discussed in this
chapter. Basic and digest authentication are discussed in much detail in
RFC2617, which can be found at
ftp://ftp.isi.edu/in-notes/rfc2617.txt.

You select one of the authentication mechanisms listed above in
/WEBINF/web.xml, like this: