CONTENTS | PREV | NEXT | INDEX Designing Enterprise Applications
with the J2EETM Platform, Second Edition



9.3 Authorization

Authorization mechanisms limit interactions with resources to collections of users or systems for the purpose of enforcing integrity, confidentiality, or availability constraints. Such mechanisms allow only authentic caller identities to access components. Mechanisms provided by the J2EE platform can be used to control access to code based on identity properties, such as the location and signer of the calling code, and the identity of the user of the calling code. As mentioned in the section on authentication, caller identity can be established by selecting from the set of authentication contexts available to the calling code. Alternatively, the caller may propagate the identity of its caller, select an arbitrary identity, or make the call anonymously.

In all cases, a credential is made available to the called component. The credential contains information describing the caller through its identity attributes. In the case of anonymous callers, a special credential is used. These attributes uniquely identify the caller in the context of the authority that issued the credential. Depending on the type of credential, it may also contain other attributes that define shared authorization properties, such as group memberships, that distinguish collections of related credentials. The identity and shared authorization attributes in the credential are referred to as the caller's security attributes. In the J2SE platform, the identity attributes of the code used by the caller may also be included in the caller's security attributes. Access to the called component is determined by comparing the caller's security attributes with those required to access the called component.

In the J2EE architecture, a container serves as an authorization boundary between the components it hosts and their callers. The authorization boundary exists inside the container's authentication boundary so that authorization is considered in the context of successful authentication. For inbound calls, the container compares security attributes from the caller's credential with the access control rules for the target component. If the rules are satisfied, the call is allowed. Otherwise, the call is rejected.

There are two fundamental approaches to defining access control rules: capabilities and permissions. Capabilities focus on what a caller can do. Permissions focus on who can do something. The J2EE application programming model focuses on permissions. In the J2EE architecture, the job of the deployer is to map the permission model of the application to the capabilities of users in the operational environment.


9.3.1 Declarative Authorization

The deployer establishes the container-enforced access control rules associated with a J2EE application. The deployer uses a deployment tool to map an application permission model, which is typically supplied by the application assembler, to policy and mechanisms specific to the operational environment. The application permission model is defined in a deployment descriptor.

The deployment descriptor defines logical privileges called security roles and associates them with components to define privileges required to be granted permission to access components. The deployer assigns logical privileges to specific callers to establish the capabilities of users in the runtime environment. Callers are assigned logical privileges based on the values of their security attributes. For example, a deployer might map a security role to a security group in the operational environment. As a result, any caller whose security attributes indicate membership in the group is assigned the privilege represented by the role. As another example, a deployer might map a security role to a list containing one or more principal identities in the operational environment. Callers then authenticated by one of these identities are assigned the privilege represented by the role.

The EJB container grants permission to access a method only to callers that have at least one of the privileges associated with the method. Security roles also protect Web resource collections, that is, a URL pattern and an associated HTTP method, such as GET. The Web container enforces authorization requirements similar to those for an EJB container.

In both tiers, access control policy is defined at deployment time, rather than during application development. The deployer can modify the policy provided by the application assembler. The deployer refines the privileges required to access the components, and defines the correspondence between the security attributes presented by callers and the container privileges. In any container, the mapping from security attributes to privileges is scoped to the application so that the mapping applied to the components of one application may be different from that of another application.


9.3.2 Programmatic Authorization

A J2EE container makes access control decisions before dispatching method calls to a component. The logic or state of the component doesn't factor in these access decisions. However, a component can use two methods, EJBContext.isCallerInRole (for use by enterprise bean code) and HttpServletRequest.isUserInRole (for use by Web components), to perform finer-grained access control. A component uses these methods to determine whether a caller has been granted a privilege selected by the component based on the parameters of the call, the internal state of the component, or other factors such as the time of the call.

The application component provider of a component that calls one of these functions must declare the complete set of distinct roleName values to be used in all calls. These declarations appear in the deployment descriptor as security-role-ref elements. Each security-role-ref element links a privilege name embedded in the application as a roleName to a security role. Ultimately, the deployer establishes the link between the privilege names embedded in the application and the security roles defined in the deployment descriptor. The link between privilege names and security roles may differ for components in the same application.

In addition to testing for specific privileges, an application component can compare the identity of its caller, acquired using EJBContext.getCallerPrincipal or HttpServletRequest.getUserPrincipal, to the distinguished caller identities embedded in the state of the component when it was created. If the identity of the caller is equivalent to a distinguished caller, the component can allow the caller to proceed. If not, the component can prevent the caller from further interaction. The caller principal returned by a container depends on the authentication mechanism used by the caller. Also, containers from different vendors may return different principals for the same user authenticating by the same mechanism. To account for variability in principal forms, an application developer who chooses to apply distinguished caller state in component access decisions should allow multiple distinguished caller identities, representing the same user, to be associated with components. This is recommended especially where application flexibility or portability is a priority.


9.3.3 Declarative versus Programmatic Authorization

There is a trade-off between the external access control policy configured by the deployer and the internal policy embedded in the application by the component provider. The external policy is more flexible after the application has been written. The internal policy provides more flexible functionality while the application is being written. In addition, the external policy is transparent and completely comprehensible to the deployer, while internal policy is buried in the application and may only be completely understood by the application developer. These trade-offs should be considered in choosing the authorization model for particular components and methods.


9.3.4 Isolation

When designing the access control rules for protected resources, take care to ensure that the authorization policy is consistently enforced across all the paths by which the resource may be accessed. For example, when method-level access control rules are applied to a component, care must be taken that a less-protected method does not serve to undermine the policy enforced by a more rigorously protected method. Such considerations are most significant when component state is shared by disparately-protected methods or URL patterns. The simplifying rule of thumb is to apply the same access control rules to all the access paths of a component and to partition an application as necessary to enforce this guideline unless there is some specific need to architect an application otherwise.

As a point of information, the CSIv2 annotations defined in IORs pertain to all the methods of an enterprise bean. This means that one cannot differentiate the protection of methods of an enterprise bean with respect to authentication, integrity, or confidentiality.


9.3.5 Affects of Identity Selection

When setting an application's access control policy, the application component provider bases policy decisions on assumptions about the call identities selected by the application callers. When a call passes through intermediary components, the caller identity at the destination component may depend on the identity selection decisions made by the intermediaries. The destination component may assume that caller identities have been propagated along the call chain so that the caller identity is that of the caller who initiated the chain. In other cases, the called component must assume that one or more of the callers in its call path will employ an identity selection policy other than identity propagation. The application assembler is responsible for communicating component identity selection policies in the deployment descriptors. In the absence of a specific representation of identity selection policy from the assembler, the deployer should assume that a component will call other components using the identity of its caller.


9.3.6 Encapsulation for Access Control

An application's component model may impose authorization boundaries around what might otherwise be unprotected resources, using accessor components to implement the authorization barrier. If accessor components are used in this way, access control can either be done externally by the container, internally by the component, or both.

An accessor component may encapsulate the mapping to an authentication context suitable for interacting with an external resource. When using principal mapping to authenticate and gain access to enterprise information system resources, authorization mechanisms applied to the accessor component can control who is authorized to access a mapping. Depending on the form of the mapping, the authorization rules may be more or less complex. For example, if all access to a resource is performed via a single conceptually omnipotent enterprise information system tier identity, then the J2EE application can implement secure access to the resource by limiting who can use the accessor. If the mapping of authentication context is many-to-many, then the authorization configuration of the accessor may need to define which of a collection of mappings are accessible to a caller and which should be assumed by default if a caller does not assert the mapping it requires.

9.3.6.1 Shared Accessor Identity

An accessor component may be given access to an external resource either by container-managed sign on or bean-managed sign on. Permissions associated with the methods of the component ensure that access to the external resource is granted only to those J2EE principals that have access to the component.

9.3.6.2 Private Accessor Identity

An enterprise bean, such as a stateful session bean, can use bean-managed sign on to an external resource. The session bean relies on a protected entity bean to map the J2EE principal to the corresponding principal in the external resource's realm, and also to the corresponding authenticator if necessary. In this scenario, either one protected entity bean holds all the mappings, and that bean limits access to a particular mapping to specific principals (returned by getCallerPrincipal), or there is one entity bean per mapping. Section 9.3.2 on page 295 describes how application developers who place a priority on application flexibility and portability must account for variability in getCallerPrincipal return values.


9.3.7 Controlling Access to J2EE Resources

A client typically uses a J2EE application's container to interact with enterprise resources in the Web or EJB tiers. These resources may be protected or unprotected. Protected resources have authorization rules defined in deployment descriptors that restrict access to some subset of non-anonymous identities. To access protected resources, users must present non-anonymous credentials to enable their identities to be evaluated against the resource authorization policy.

9.3.7.1 Controlling Access to Web Resources

To control access to a Web resource, an application component provider or application assembler specifies a security-constraint element with an auth-constraint subelement in the Web deployment descriptor. Code Example 9.7 illustrates the definition of a protected resource in a Web component deployment descriptor. The descriptor specifies that the URL /control/placeorder can be accessed only by users acting in the role of customer.

<security-constraint>
	<web-resource-collection>
		<web-resource-name>placeorder</web-resource-name>
		<url-pattern>/control/placeorder</url-pattern>
		<http-method>POST</http-method>
		<http-method>GET</http-method>
	</web-resource-collection>
	<auth-constraint>
		<role-name>customer</role-name>
	</auth-constraint>
</security-constraint>
Code Example 9.7 Web Resource Authorization Configuration

9.3.7.2 Controlling Access to Enterprise Beans

An application component provider or application assembler that has defined security roles for an enterprise bean can also specify the methods of the bean's remote, home, local, and local home interfaces that each security role is allowed to invoke. This is done in the form of method-permission elements. Ultimately, the assignment of users to roles determines if a resource is protected. When the roles required to access the enterprise bean are assigned only to authenticated users, the bean is protected.

Code Example 9.8 contains two styles of method specifications. The first refers to all of the methods of all of the interfaces (that is, remote, home, local, and local home) of an enterprise bean. The second refers to a specific method that occurs on an interface of an enterprise bean. If there are multiple methods with the same overloaded name, this style refers to all overloaded methods. Method specifications can be further qualified to identify methods with overloaded names by parameter signature, or to refer to methods of a specific interface of the enterprise bean.

<method-permission>
	<role-name>admin</role-name>
		<method>
			<ejb-name>TheOrder</ejb-name>
			<method-name>*</method-name>
		</method>
</method-permission>

<method-permission>
	<role-name>customer</role-name>
	<method>
		<ejb-name>TheOrder</ejb-name> 
		<method-name>getDetails</method-name> 
	</method>
	<method>
	...
</method-permission>
Code Example 9.8 Enterprise Bean Authorization Configuration

In addition to the authorization policy defined in method-permission elements, method specifications may be added to the exclude-list to indicate that access to them is to be denied independent of caller identity and whether the methods are the subject of a method-permission element. Code Example 9.9 demonstrates the use of the exclude-list.

<exclude-list>
	<method>
		<ejb-name>SpecialOrder</ejb-name>
		<method-name>*</method-name>
	</method>
	<method>
	...
</exclude-list>
Code Example 9.9 Enterprise Bean Excluded method-permission

9.3.7.3 Unprotected Resources

Many applications feature unprotected Web-tier content, available to any caller without authentication. Unprotected resources are characterized by the absence of a requirement that their caller be authenticated. In the Web tier, unrestricted access is provided simply by leaving out an authentication rule.

Some applications also feature unprotected enterprise beans. For example, the sample application allows anonymous, unauthenticated users to access certain EJB resources. In the EJB tier, the application assembler uses the unchecked element in the method-permission element to indicate that the methods covered by the specification are to be authorized by the container, independent of the identity of the caller. Code Example 9.10 demonstrates the use of the unchecked element.

<method-permission>
	<unchecked/>
	<method>
		<ejb-name>Catalogue</ejb-name> 
		<method-name>browseSpecials</method-name> 
	</method>
	<method>
	...
</method-permission>
Code Example 9.10 Enterprise Bean Unchecked method-permission

9.3.8 Example

To understand how each application, and each component within an application, can apply its own authorization requirements, consider the following examples.

One application is assembled from two enterprise beans, EJB 1 and EJB 2, each with one method. Each method calls isCallerInRole with the role name MANAGER. The deployment descriptor includes a security-role-ref element for the call to isCallerInRole in each enterprise bean. The security-role-ref for EJB 1 links MANAGER to the role good-managers and the security-role-ref element for EJB 2 links MANAGER to the role bad-managers. The deployment descriptor defines two method-permission elements. One establishes that the role employees can access all methods of EJB 1 and the other does the same for EJB 2. The deployment descriptor has 3 security-role elements: employees, good-managers, and bad-managers. The deployer assigns User 1 to roles employees and good-managers and assigns User 2 to roles employees and bad-managers.

A second application, with one enterprise bean EJB 3, is also deployed in the container. EJB 3 also makes a call to isCallerInRole with the role name MANAGER. The deployment descriptor for this second application contains a security-role-ref element that links MANAGER to the role good-managers. Similarly, the deployment descriptor defines one method-permission element that establishes that the role employees can access all the methods of EJB 3. The deployment descriptor has 2 role elements, employees and good-managers. The deployer assigns User 2 to roles employees and good-managers.

Figure 9.5 illustrates the configuration of method permissions as a relationship between roles and methods. It also illustrates the mapping of caller security attributes to roles, and the link between privilege names embedded in the application and roles.

Table 9.1 lists the authorization decisions that occur when different users initiate method calls on these enterprise beans. For example, when User 1 initiates a method call on EJB 2's method, the container dispatches the call because the method-permission element specifies the security roles employees and good-managers, and the deployer has assigned User 1 to the employees security role. However, the isCallerInRole("MANAGER") method returns false, because the security-role-ref element for EJB 2 links MANAGER to the security role bad-managers, which is not satisfied for User 1. When User 1 invokes a method on EJB 3, the call isn't even dispatched, because User 1 isn't assigned to any security roles.

Figure 9.5 Authorization Scenario

Authorization Decisions 

Call

Call Dispatched?

isCallerInRole?

User 1 - EJB 1

yes

true

User 1 - EJB 2

yes

false

User 1 - EJB 3

no

never called

User 2 - EJB 1

yes

false

User 2 - EJB 2

yes

true

User 2 - EJB 3

yes

true



CONTENTS | PREV | NEXT | INDEX
Copyright © 2002 Sun Microsystems, Inc. All Rights Reserved.