Web applications are created by application developers who give, sell, or otherwise transfer the application to an application deployer for installation into a runtime environment. Application developers communicate how the security is to be set up for the deployed application declaratively by use of the deployment descriptor mechanism. A deployment descriptor enables an application’s security structure, including roles, access control, and authentication requirements, to be expressed in a form external to the application.
A web application is defined using a standard Java EE web.xml deployment descriptor. A deployment descriptor is an XML schema document that conveys elements and configuration information for web applications. The deployment descriptor must indicate which version of the web application schema (2.4 or 2.5) it is using, and the elements specified within the deployment descriptor must comply with the rules for processing that version of the deployment descriptor. Version 2.5 of the Java Servlet Specification, which can be downloaded at SRV.13, Deployment Descriptor, contains more information regarding the structure of deployment descriptors.
The following code is an example of the elements in a deployment descriptor that apply specifically to declaring security for web applications or for resources within web applications. This example comes from section SRV.13.5.2, An Example of Security, from the Java Servlet Specification 2.5.
<?xml version="1.0" encoding="ISO-8859-1"?> <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_5.xsd" version="2.5"> <display-name>A Secure Application</display-name> <!-- SERVLET --> <servlet> <servlet-name>catalog</servlet-name> <servlet-class>com.mycorp.CatalogServlet</servlet-class> <init-param> <param-name>catalog</param-name> <param-value>Spring</param-value> </init-param> <security-role-ref> <role-name>MGR</role-name> <!-- role name used in code --> <role-link>manager</role-link> </security-role-ref> </servlet> <!-- SECURITY ROLE --> <security-role> <role-name>manager</role-name> </security-role> <servlet-mapping> <servlet-name>catalog</servlet-name> <url-pattern>/catalog/*</url-pattern> </servlet-mapping> <!-- SECURITY CONSTRAINT --> <security-constraint> <web-resource-collection> <web-resource-name>CartInfo</web-resource-name> <url-pattern>/catalog/cart/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <!-- LOGIN CONFIGURATION--> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>
As shown in the preceding example, the <web-app> element is the root element for web applications. The <web-app> element contains the following elements that are used for specifying security for a web application:
<security-role-ref>
The security role reference element contains the declaration of a security role reference in the web application’s code. The declaration consists of an optional description, the security role name used in the code, and an optional link to a security role.
The security role name specified here is the security role name used in the code. The value of the role-name element must be the String used as the parameter to the HttpServletRequest.isUserInRole(String role) method. The container uses the mapping of security-role-ref to security-role when determining the return value of the call.
The security role link specified here contains the value of the name of the security role that the user may be mapped into. The role-link element is used to link a security role reference to a defined security role. The role-link element must contain the name of one of the security roles defined in the security-role elements.
For more information about security roles, read Working with Security Roles.
<security-role>
A security role is an abstract name for the permission to access a particular set of resources in an application. A security role can be compared to a key that can open a lock. Many people might have a copy of the key. The lock doesn’t care who you are, only that you have the right key.
The security-role element is used with the security-role-ref element to map roles defined in code to roles defined for the web application. For more information about security roles, read Working with Security Roles.
<security-constraint>
A security constraint is used to define the access privileges to a collection of resources using their URL mapping. Read Specifying Security Constraints for more detail on this element. The following elements can be part of a security constraint:
<web-resource-collection> element: Web resource collections describe a URL pattern and HTTP method pair that identify resources that need to be protected.
<auth-constraint> element: Authorization constraints indicate which users in specified roles are permitted access to this resource collection. The role name specified here must either correspond to the role name of one of the <security-role> elements defined for this web application, or be the specially reserved role name *, which is a compact syntax for indicating all roles in the web application. Role names are case sensitive. The roles defined for the application must be mapped to users and groups defined on the server. For more information about security roles, read Working with Security Roles.
<user-data-constraint> element: User data constraints specify network security requirements, in particular, this constraint specifies how data communicated between the client and the container should be protected. If a user transport guarantee of INTEGRAL or CONFIDENTIAL is declared, all user name and password information will be sent over a secure connection using HTTP over SSL (HTTPS). Network security requirements are discussed in Specifying a Secure Connection.
<login-config>
The login configuration element is used to specify the user authentication method to be used for access to web content, the realm in which the user will be authenticated, and, in the case of form-based login, additional attributes. When specified, the user must be authenticated before access to any resource that is constrained by a security constraint will be granted. The types of user authentication methods that are supported include basic, form-based, digest, and client certificate. Read Specifying an Authentication Mechanism for more detail on this element.
Some of the elements of web application security must be addressed in server configuration files rather than in the deployment descriptor for the web application. Configuring security on the Application Server is discussed in the following sections and books:
The following sections provide more information on deployment descriptor security elements:
Security constraints are a declarative way to define the protection of web content. A security constraint is used to define access privileges to a collection of resources using their URL mapping. Security constraints are defined in a deployment descriptor. The following example shows a typical security constraint, including all of the elements of which it consists:
<security-constraint> <display-name>ExampleSecurityConstraint</display-name> <web-resource-collection> <web-resource-name> ExampleWRCollection </web-resource-name> <url-pattern>/example</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>exampleRole</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
As shown in the example, a security constraint (<security-constraint> in deployment descriptor) consists of the following elements:
Web resource collection (web-resource-collection)
A web resource collection is a list of URL patterns (the part of a URL after the host name and port which you want to constrain) and HTTP operations (the methods within the files that match the URL pattern which you want to constrain (for example, POST, GET)) that describe a set of resources to be protected.
Authorization constraint (auth-constraint)
An authorization constraint establishes a requirement for authentication and names the roles authorized to access the URL patterns and HTTP methods declared by this security constraint. If there is no authorization constraint, the container must accept the request without requiring user authentication. If there is an authorization constraint, but no roles are specified within it, the container will not allow access to constrained requests under any circumstances. The wildcard character * can be used to specify all role names defined in the deployment descriptor. Security roles are discussed in Working with Security Roles.
User data constraint (user-data-constraint)
A user data constraint establishes a requirement that the constrained requests be received over a protected transport layer connection. This guarantees how the data will be transported between client and server. The choices for type of transport guarantee include NONE, INTEGRAL, and CONFIDENTIAL. If no user data constraint applies to a request, the container must accept the request when received over any connection, including an unprotected one. These options are discussed in Specifying a Secure Connection.
Security constraints work only on the original request URI and not on calls made throug a RequestDispatcher (which include <jsp:include> and <jsp:forward>). Inside the application, it is assumed that the application itself has complete access to all resources and would not forward a user request unless it had decided that the requesting user also had access.
Many applications feature unprotected web content, which any caller can access without authentication. In the web tier, you provide unrestricted access simply by not configuring a security constraint for that particular request URI. It is common to have some unprotected resources and some protected resources. In this case, you will define security constraints and a login method, but they will not be used to control access to the unprotected resources. Users won’t be asked to log in until the first time they enter a protected request URI.
The Java Servlet specification defines the request URI as the part of a URL after the host name and port. For example, let’s say you have an e-commerce site with a browsable catalog that you would want anyone to be able to access, and a shopping cart area for customers only. You could set up the paths for your web application so that the pattern /cart/* is protected but nothing else is protected. Assuming that the application is installed at context path /myapp, the following are true:
http://localhost:8080/myapp/index.jsp is not protected.
http://localhost:8080/myapp/cart/index.jsp is protected.
A user will not be prompted to log in until the first time that user accesses a resource in the cart/ subdirectory.
You can create a separate security constraint for different resources within your application. For example, you could allow users with the role of PARTNER access to the POST method of all resources with the URL pattern /acme/wholesale/*, and allow users with the role of CLIENT access to the POST method of all resources with the URL pattern /acme/retail/*. An example of a deployment descriptor that would demonstrate this functionality is the following:
// SECURITY CONSTRAINT #1 <security-constraint> <web-resource-collection> <web-resource-name>wholesale</web-resource-name> <url-pattern>/acme/wholesale/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>PARTNER</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> // SECURITY CONSTRAINT #2 <security-constraint> <web-resource-collection> <web-resource-name>retail</web-resource-name> <url-pattern>/acme/retail/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>CLIENT</role-name> </auth-constraint> </security-constraint>
When the same url-pattern and http-method occur in multiple security constraints, the constraints on the pattern and method are defined by combining the individual constraints, which could result in unintentional denial of access. Section 12.7.2 of the Java Servlet 2.5 Specification (downloadable from http://jcp.org/en/jsr/detail?id=154) gives an example that illustrates the combination of constraints and how the declarations will be interpreted.