JAAS in Action by Coté / www.JAASbook.com / www.DrunkAndRetired.com
This work is licensed under a Creative Commons Attribution-NonCommercial 2.5
License: http://creativecommons.org/licenses/by-nc/2.5/
9 JAAS in Web Applications
Though the Servlet spec doesn’t officially integrate with JAAS, by convention, most Servlet
containers provide several JAAS-related functions: restricting access to pages in a web
application, providing a framework to authenticate users, and methods to access
authentication information. Pages restrictions are specified by URL patterns and a list of
“role” names that the requesting user must have to access the URLs. How these role names
map to Principals is not specified, but in Tomcat, the role names are simply the String
names of Principals. The framework for authenticating users can be used to create login
screens that gather a user’s username and password, and then associate the authenticated user
with the session. The methods for accessing authentication information allow you to
programmatically verify which Principals a user is in, retrieve their Servlet-centric
Principals, and access other security-related state.
9.1 The Web Application
This chapter uses a simple web application, diagramed above, with a handful of pages to
demonstrate each of the above integration points between JAAS and Servlets. The web
application provides a home page with links to an admin page, a customer page, and support
pages to log in users, log out users, and an error page. As their names suggest, a user must be
authenticated as an admin to access the admin page and a customer to access the customer
JAAS in Action by Coté / www.JAASbook.com / www.DrunkAndRetired.com
This work is licensed under a Creative Commons Attribution-NonCommercial 2.5
License: http://creativecommons.org/licenses/by-nc/2.5/
page. Also, this chapter discusses a simple custom tag library that displays it’s body content
based on an authenticated user’s Principal set.
9.2 Configuring JAAS with Servlets
To enable JAAS in a web application, three things must be configured. First, the web
container must be configured to create a “realm” that will be used to authenticate users. The
Servlet spec does not specify how this configuration is done, so it’s different for each web
container. Once a realm is setup, the web.xml file must be modified to enable the
authentication framework and to include mappings of URL patterns to the Principal
names required to access those URLs. Finally, JAAS must itself be configured to specify the
LoginModule implementations to use when authenticating a user.
9.2.1 Configuring Realms
A realm has one responsibility: authenticate a user based on a username and password, adding
“roles” to that user if authentication was successful. The Servlet spec doesn’t specify how
this responsibility is implemented, or very many other semantics of realms except that a
realm must be able to represent roles with String names. Because of this looseness, each web
container implementation is able to provide many different realm implementations: simple
flat-file based realms, LDAP or other directory-based realms, OS authentication realms, and
many other methods. Practically ever web container also provides a way to use JAAS as a
realm. In the instances when JAAS is used as a Servlet realm, the web container gathers a
user’s username and password credentials, and delegates authenticating the user to the JAAS
authentication framework, using a LoginContext and LoginModule implementations.
In this chapter, we use Tomcat 5.0.28 as our web container. Tomcat is the reference
implementation for the Servlet 2.4 specification, and it provides a simple way to use JAAS
realms. Realms are configured in Tomcat by modifying either the system-wide server.xml,
or the web application’s uniquely named server.xml. In our example, we modify the second
to keep our application as self-contained as possible.
Modifying server.xml
Web application server.xml files are stored in <tomcat
dir>/conf/Catalina/localhost/ and follow the convention of being named the same as
their corresponding web application. Our web application is named jaas-book-chp09, so
the server.xml file we’re interested in is found at <tomcat
dir>/conf/Catalina/localhost/jaas-book-chp09.xml. The content of the file is
below:
<?xml version="1.0"?>
<Context path="/jaas-book-chp09" docBase="~/tomcat/webapps/jaas-book-
chp09"
debug="0" reloadable="true">
<Realm className="org.apache.catalina.realm.JAASRealm" #1
appName="chp09" #2
JAAS in Action by Coté / www.JAASbook.com / www.DrunkAndRetired.com
This work is licensed under a Creative Commons Attribution-NonCommercial 2.5
License: http://creativecommons.org/licenses/by-nc/2.5/
userClassNames="chp09.UserPrincipal" |#3
roleClassNames="chp04.UserGroupPrincipal" |#3
useContextClassLoader="false"/> #4
</Context>
(annotation) <#1: The realm tag specifies that Tomcat’s JAASRealm will be used to authenticate users.
(annotation) <#2: appName is used to specify which LoginModule group will be used to authenticate users. “chp09”
is the application name that will be passed into the LoginContext constructor. So, we’ll have to ensure that our
javax.security.login.Configuration can return an AppConfigurationEntry array for that
application name.>
(annotation) <#3: The userClassNames and roleClassNames attributes specify which Principal
implementations will be used to represent the user Principal and the role Principals. On ce a user has been
authenticated, creating a Subject with Principals, the user Principal is used when the web container looks
up the Subject’s user, for example, when looking up the value for HttpServletRequest’s
getRemoteUser() o r getUserPrincipal(). The role Principals are used to lookup the Subject’s
roles, for example, when resolving if a user is in a role for HttpServletRequest’s isUserInRole.>
(annotation) <#4: setting this attribute to false tells Tomcat to use the web application’s class loader instead of the
server class loader. The LoginModule implementation we’ll be using (DbLoginModule and
TomcatLoginModule) will be stored in the web application’s lib directory, meaning that the server level class
loader will not be able to find it.>
With chp09-server.xml in place, Tomcat will create an authentication realm that will
be used once we configure web.xml to enable security.
9.2.2 Configuring web.xml
As with practically ever other feature in Servlets, enabling authentication and authorization is
done by modifying the web.xml file. Three tags are used to enable authentication, specify
URL access restrictions, and define the available user roles, or Principals.
Enabling Authentication
Web containers may provide five types of authentication schemes: BASIC and DIGEST,
which use the built in username and password dialog box for HT T P; FORM, which uses
custom JSP pages with standard form action and element names; CLIENT-CERT, which uses
digital certificates; and any proprietary mechanisms that the web container provides. In this
book, we’ll only cover the use of the FORM method because it covers the widest range of
cases and allows for a fair amount of customization.
In our example web application, configuring authorization in web.xml is done with the
following element:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Chp09 Realm</realm-name> #1
<form-login-config> #2
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login-error.jsp</form-error-page>
</form-login-config>
</login-config>
(annotation <#1: the realm name is used purely for display purposes, mostly for web application development tools.>
JAAS in Action by Coté / www.JAASbook.com / www.DrunkAndRetired.com
This work is licensed under a Creative Commons Attribution-NonCommercial 2.5
License: http://creativecommons.org/licenses/by-nc/2.5/
(annotation) <#2: this element and its sub-elements specify the location of the login page to use and JSP page to use
when authentication er ro rs occu r. The erro r page is used for invalid login attempts and when erro rs occur logging
in. A different page, covered below, is used when a user attempts to access a URL they’re not authorized to view.>
Locking Down URLs with security-constraints
To specify access control for parts of your web application, you use any number of
security-constraint elements. The security-constraint element specifies one or
more URL patterns and the Principals, represented by role names, a user is required to
have to access those URLs. When an unauthenticated user attempts to request one of the
protected URL, the web container redirects the request to the login page specified in the
login-config element in web.xml.
A URL pattern can be an exact match, like /admin/userlist.jsp, or a pattern, like
/admin/*. The first pattern specifies a single page, while the second specifies any URLs that
begin with /admin. The patterns are all relative to the web application context.
The role names specified may either be the String name of a Principal, or the special
role name *, which is shorthand for any role. When a user requests a URL specified by the
security-constraints URL patterns, the users Subject must have one of the roles
specified, or access is denied.
The security-constraint elements used in our example web.xml are below:
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Page (Chp09)</web-resource-name>
<url-pattern>/admin/*</url-pattern> #1
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name> #2
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Customer Page (Chp09)</web-resource-name>
<url-pattern>/customer/*</url-pattern> #1
</web-resource-collection>
<auth-constraint>
<role-name>customer</role-name> #2
</auth-constraint>
</security-constraint>
(annotation) <#1: these tags specify the URLs that have access restrictions. The URL patterns used in this example
cover all URLs that begin with /admin and all URLs that begin with /customer. Each URL is relative to the web
application context.>
(annotation) <#2: the Principals required to access restricted URLs are specified in the auth-constraint
element by role-name elements. Any number of role-name elements may be specified. Each role-name
element specifies one Principal, by name, that may access the restricted URL. If none are specified, then no users
may access the restricted URLs, preventing all access to the URLs.>
Specifying the roles Used
JAAS in Action by Coté / www.JAASbook.com / www.DrunkAndRetired.com
This work is licensed under a Creative Commons Attribution-NonCommercial 2.5
License: http://creativecommons.org/licenses/by-nc/2.5/
Finally, you must specify all of the role names that are referenced in web.xml with one
security-role element per role. Specifying each role that’s used seems tedious, but it
allows tools to get a list of roles used and provides crude referential integrity
1
.
The security-role elements for our example web application are below:
<security-role>
<description>
Role required to see admin pages.
</description>
<role-name>admin</role-name>
</security-role>
<security-role>
<description>
Role required to see customer pages.
</description>
<role-name>customer</role-name>
</security-role>
Other Settings and Entire web.xml Listing
The entire web.xml listing is below, with code notations for the remainder of the settings:
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>jaas-book</display-name>
<description>JAAS Book, Chapter 9</description>
<servlet>
<servlet-name>InitServlet</servlet-name> #1
<servlet-class>chp09.StartupServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page> #2
<error-code>403</error-code>
<location>/access-denied.jsp</location>
</error-page>
1
Tomcat allows you to skip specifying the security-role element, but logs an error if you
omit them. Other web containers may not be so forgiving.
评论2