The J2EE container-based security services primarily address the security requirements of the application tiers and components. They provide authentication and authorization mechanisms by which callers and service providers prove each other's identities, and then they provide access control over the resources to which an identified user or system has access. A J2EE container supports two kinds of security mechanisms. Declarative security allows enforcement of security using a declarative syntax applied during the application's deployment. Programmatic security allows expressing and enforcing security decisions at the application's invoked methods and its associated parameters. Declarative SecurityIn a declarative security model, the application security is expressed using rules and permissions in a declarative syntax specific to the J2EE application environment. The security rules and permissions will be defined in a deployment descriptor document packaged along with the application component. The application deployer is responsible for assigning the required rules and permissions granted to the application in the deployment descriptor. Figure 5-2 shows the deployment descriptors meant for different J2EE components. Figure 5-2. J2EE deployment descriptors
Example 5-1 is an XML snippet from a Web application deployment descriptor (web.xml) that represents a security constraint defining an access control policy for a Web application resource (/products/apply-discount) and specifies the access privileges for a role (employee). Example 5-1. Security constraints in Web application deployment descriptor<security-constraint> <web-resource-collection> <web-resource-name>apply-discount</web-resource-name> <url-pattern>/products/apply-discount</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>employee</role-name> </auth-constraint> </security-constraint> Programmatic SecurityIn a programmatic security model, the J2EE container makes security decisions based on the invoked business methods to determine whether the caller has been granted a privilege to access or deny a resource. This determination is based on the parameters of the call, its internal state, or other factors based on the time of the call or its processed data. For example, an application component can perform fine-grained access control with the identity of its caller by using EJBContext.getCallerPrincipal (EJB component) or HttpServletRequest.getUserPrincipal (Web component) and by using EJBContext.isCallerInRole (EJB component) and HttpServletRequest.isUserInRole (Web component). This allows determining whether the identity of the caller has the privileged role to execute a method for accessing a protected resource. Using programmatic security helps when declarative security is not sufficient to build the security requirements of the application component and where the component access control decisions need to use complex and dynamic rules and policies. J2EE AuthenticationWhen a client interacts with a J2EE application, depending upon the application component architecture, it accesses a set of underlying components and resources such as JSPs, Servlets, EJBs, Web services endpoints, and other back-end applications. Because processing a client request involves a chain of invocations with subsequent components and resources, the J2EE platform allows introducing a client authentication at the initial call request. After initial authentication, the client identity and its credentials can be propagated to the subsequent chain of calls. The J2EE platform allows establishing user authentication in all application tiers and components. The J2EE environment provides support for the following three types of authentication services:
Container-Based AuthenticationThis is the standard authentication service provided by the J2EE server infrastructure. This allows the J2EE environment to authenticate users for access to its deployed applications. The J2EE specification mandates Web container support for four authentication types, which include the following: HTTP Basic AuthenticationThe Web container component authenticates a principal using a username and password dialog from the Web client. Form-Based AuthenticationSimilar to Basic Authentication, but the login dialog is customized as a form to pass the username and password to the Web container. Client/Server Mutual AuthenticationBoth the client and server use X.509 certificates to establish their identities, and this authentication usually occurs over a secure communication channel using SSL/TLS protocols. HTTP Digest AuthenticationWith HTTP digest authentication, the client authenticates to the server using a message digest containing the client password and sends it with the HTTP request message. These authentication types can also be performed in the EJB Business Tier, which involves a Web component that receives a user request and then invokes an EJB component on the EJB Tier. In a Web component-to-EJB interaction scenario, the application uses a Web component in front of the EJB component to provide authentication. While integrating with back-end enterprise applications such as EIS and databases, the J2EE environment provides a container-managed resource manager sign-on authentication. This allows engaging authentication with the client caller, including Web and Business Tier components. Application-Based AuthenticationIn application-based authentication, the application relies on a programmatic security approach to collect the user credentials and verifies the identity against the security realm. In a Web-componentbased application, the servlet adopts the authentication mechanisms from the J2EE container services and then uses declarative security mechanisms to map the user principal to a security role defined in the deployment descriptor. Agent-Based AuthenticationThis allows J2EE applications to use third-party security providers for authentication. The security providers provide pluggable agents typically to provide a single sign-on solution to portals, J2EE-managed business applications, and so forth. The agent usually resides as a proxy that intercepts the user requests to the J2EE server. Typically, to support agent-based authentication, the J2EE server infrastructure uses JAAS-based authentication modules to integrate custom authentication technologies. Protection DomainsIn the J2EE platform, the container provides an authentication boundary between the external callers and the deployed components. It is the container's responsibility to enforce the security within its boundary and ensure that calls entering are authenticated and identified within the boundary for all interactions. Interactions within the container-managed boundary are managed as protection domains, which maintain the identity proof for the interacting components to trust each other. Figure 5-3 illustrates the notion of protection domains. Figure 5-3. Protection domainsWhen a user makes an inbound request to the container to invoke a J2EE component, it is the container's responsibility to ensure that the authentication information is available to the component as a credential. Similarly, in the case of outbound calls, it is the container's responsibility to maintain the caller's identity to enforce the protection domain to the called components. In a J2EE component deployment, this is done by declaring the resource references (e.g., resource-ref element) in the deployment descriptor of the J2EE component that interacts with other components and external resources managed by the container. J2EE AuthorizationJ2EE uses a role-based authorization model to restrict access control with components and resources. The role is a logical grouping of users defined by the application assembler. The application deployer maps the users to roles in the target environment. In a J2EE environment, the container serves as the authentication boundary between the components and its caller clients. When a client initiates a request with a successful authentication, the container verifies the security attributes from the client's credentials and identifies the access control rules for the target resource. If the rules are satisfied, the container allows the caller to access the resource; otherwise, it denies the request. The J2EE platform provides the following two types of authorization mechanisms:
Declarative AuthorizationIn a J2EE environment, the application deployer specifies the enforced rules and permissions associated with an application. The rules and resources are listed in the application deployment descriptor along with a list of roles that are able to access the resource. These roles are mapped to specific users by the application deployer. In Web components such as JSPs and Servlets, access can be protected at the URL level, and it can be further protected down to GET or POST methods. In EJB components, permissions can be specified down to specific class methods. Because declarative authorization is based on a static policy, it has limitations when the enforcing of dynamic access rules, multi-role access, and content-level authorization is required. Unless these requirements are demanded, declarative authorizations are usually preferred and easier to deploy. Programmatic AuthorizationThe J2EE container decides on access control before forwarding the requests to a component. In programmatic authorization, the access control rule and associated logic is directly implemented into the application. For example: Using EJBContext.isCallerInRole() and EJBContext.getCallerPrincipal() in EJB components and using HttpServletRequest.isUserInRole() and HttpServletRequest.getUserPrincipal() in Web components provide finer-grained access control than declarative authorization provides. Using programmatic authorization allows implementing security-aware J2EE applications that can enforce access control mechanisms such as dynamic access rules, multi-role access, and content-level authorization. Java Authorization Contract for Client Containers (JACC)Java Authorization Contract for Containers (JACC) defines a set of security contracts between the J2EE application containers and authorization policy modules. These contracts specify how the pluggable authorization policy providers are installed, configured, and used in access decisions. JACC was introduced as a mandatory part of the J2EE 1.4 platform, which defines a new set of java.security.Permission classes that support role-based authorization. The JACC provider is set as a <security-service> element in the J2EE environment config file. For example, in Sun J2EE 1.4 reference implementation (Sun Java System Application Server 8Platform Edition), using a simple file-based JACC authorization engine is shown in the domain.xml as shown in Example 5-2. Example 5-2. File-based JACC authorization engine configuration<security-service jacc="default"> <jacc-provider name="default policy-provider= "com.sun.enterprise.security.provider.PolicyWrapper" policy-configuration-factory-provider= "com.sun.enterprise.security.provider.PolicyConfigurationFactoryImpl"> <property name="repository" value="jesdomain/mypolicy"/> </jacc-provider> </security-service> Transport Layer SecurityThe J2EE platform facilitates secure communication by adopting transport layer integrity and confidentiality mechanisms based on SSL/TLS protocols. This ensures a tamperproof encrypted message between the communicating entities. The SSL/TLS transport security properties are configured at the container level and will be applied to communication during the creation of the connection. In addition, J2EE provides configuration features that enforce protected communication and reject unprotected requests and responses. SSL/TLS-based communication security can be specified for Web components and EJB components, including their Web services endpoints. It is the responsibility of the J2EE application assembler to identify the components with method calls whose parameters or return values should be protected for integrity or confidentiality. The component's deployment descriptor is used to represent this information. To secure communication with Web components such as Servlets and JSP pages, the transport-guarantee sub-element of the user-data-constraint sub-element of a security-constraint is used. In cases where a component's interactions with an external resource are known to carry sensitive information, these sensitivities should be described in the description sub-element of the corresponding resource-ref. In EJB components, this is done in a description sub-element of the target EJB component. Example 5-3 illustrates a Web deployment descriptor snippet (web.xml) showing the <transport-guarantee> sub-element. Example 5-3. Web deployment descriptor showing the <transport-guarantee> sub-element<security-constraint> . . . <user-data-constraint> <transport-guarantee> CONFIDENTIAL </transport-guarantee> </user-data-constraint> . . . </security-constraint> In the previous sections, we briefly looked at the different security mechanisms and services made available by the J2EE environment. Now, we will look over the different component-level security mechanisms that encompass all the logical tiers and components. |