Read an Excerpt
Chapter 9: SecurityComputer 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 AuthenticationServlet authentication looks simple:
1. A user tries to access a protected resource, such as a JSP page.
2. If the user has been authenticated, the servlet container makes the resource available; otherwise, the user is asked for a username and password.
3. 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" on page 254 for more information.
Principals and RolesIn 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:
<web-app> ... <security-constraint> <!-- web resources that are protected --> <web-resource-collection> <web-resource-name>Protected Resource</web-resource-name> <url-pattern>/page_1.jsp</url-pattern> </web-resource-collection> <auth-constraint> <!-- role-name indicates roles that are allowed to access the web resources specified above --> <role-name>customer</role-name> <auth-constraint> </security-constraint> ... <security-constraint> <!-- web resources that are protected --> <web-resource-collection> <web-resource-name>Protected Resource2</web-resource-name> <url-pattern>/page_2.jsp</url-pattern> </web-resource-collection> <auth-constraint> <!-- role-name indicates roles that are allowed to access the web resources specified above --> <role-name>employee </auth-constraint> </security-constraint> <web-app>
Two security constraints are specified above that restrict access to
/page_2.jsp to principals that are in roles customer or employee,
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
<tomcat-users> ... <user name="rwhite" password="tomcat" roles="customer", "other"/> ... </tomcat-users>
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" on page 264 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....
...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" on page 271 for more information.
Table 9-2 lists other ServletRequest methods that provide security information....
...Like the methods listed in Table 9-1 on page 253, 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 AuthenticationDeclarative 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 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. "Basic Authentication" on page 256 provides an example of declarative authentication, "Customizing Authentication" on page 263 illustrates customizing authentication, and programmatic authentication is discussed in "Programmatic Authentication" on page 271.
PortabilityThe 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....
1. This chapter is based upon the 2.2 Servlet specification; for specification links, see