11.3 Application Provider's View of SecurityAn EJB application provider has essentially two choices for managing security:
We discuss these two options from the perspective of user authentication and authorization. 11.3.1 Client AuthenticationWe recommend that EJB applications not perform user authentication logic in the application code. Instead, developers of EJB applications should rely on the deployer to ensure that the caller of an enterprise bean method has been authenticated prior to invoking the method. At runtime, the EJB container authenticates the client before the container dispatches a business method. The container makes the identity of the method caller available to the invoked enterprise bean method via the getCallerPrincipal method of the EJBContext interface. Why is it recommended that EJB applications not perform authentication logic? There are two reasons for this recommendation:
11.3.2 AuthorizationThe guidelines for implementing authorization the rules that specify which users can perform which business functions are less straightforward than those for authentication. Ideally, authorization rules should be decoupled from the application code. This permits the rules to be set based on the operational environment and lets the container be responsible for their enforcement. When decoupled from the application code, the deployer can modify the authorization rules to meet the unique needs of the particular operational environment. Furthermore, decoupling the authentication logic from the application code enables the container to enforce the authentication rules rather than rely on the application to make the authorization checks itself. Because a vendor with expertise in security typically develops the container, the application overall is more secure when the container enforces the authentication rules. In practice, however, many authorization rules are too fine grained or too application specific that is, the rules may be a function of data passed by the client and data read from a database to be decoupled from the application code. An example is a rule that states the following: An expense request larger than $5,000 must be approved by the division's vice president unless the requester is at least a director in the company, or the item to be expensed was purchased from a list of preapproved suppliers. Consequently, developers must evaluate their own applications and decide whether to delegate an authorization rule to the container to enforce or to handle the rule as part of the application's business logic and thus code its treatment in the application. We recommend using the following guidelines for this decision:
11.3.3 Declarative Security MechanismAs mentioned previously, the EJB declarative security mechanism allows decoupling of a certain type of authentication rules from the business logic of the application. The application provider uses the deployment descriptor to define a set of security roles and their associated method permissions for the enterprise beans. This information represents the client authorization rules intended by the application provider. The deployer uses this information as input when securing the application in a specific operational environment (Figure 11.2). Figure 11.2. Declarative Security MechanismsThe definitions of the security roles and their associated method permissions simplify the deployer's task. The definitions of the security roles free the deployer from having to learn each enterprise bean method's function to determine who should be allowed to invoke that method. Instead, the deployer needs to understand a much smaller set of security roles to secure the application. 11.3.4 Security RolesThe definitions of the security roles advise the deployer on how the application provider envisioned the application would be used from a security perspective. Each security role represents an actor a type of user for the application. Each actor performs one or more use cases. For example, Wombat, which developed the Benefits Enrollment application, may define two security roles in the benefits_ejb.jar file deployment descriptor:
11.3.5 Method PermissionsIn the deployment descriptor, a method permission is a declaration pertaining to security roles. You can think of a method permission as stating that a given security role invokes a given enterprise bean method when running the application. A method permission declaration instructs the tools used by the deployer to ensure that the users with the specified security role be allowed to invoke the method. In addition, the developer or assembler may mark a method as being unchecked or uncallable. For a method marked unchecked, no authorization checks are performed prior to invoking the method. A method marked uncallable is a method that may never be called. For example, Wombat uses the method permission mechanism in the deployment descriptor to declare the following:
How do security roles and method permissions simplify the deployer's task? When deploying the premiumhealth_ejb.jar file, the deployer is concerned only with the two security roles: employee and benefits-admin. The deployer does not have to study each individual enterprise bean method's function. Typically, the deployment tools display the security roles and prompt the deployer to assign individual users or user groups, to each security role. The tools and the EJB container automatically ensure that assigned users or user groups have access to the methods specified in the method permissions. 11.3.6 Using the RunAs PrincipalNormally, an enterprise bean executes in the security context of the caller. This implies that by default, any resources or other beans used by the first bean are also accessed under the client's security context or without a security context, if the client's request was not secured. The application developer or assembler can change the principal under which resources and other beans are accessed by a bean by setting a RunAs principal for the bean. This is done by specifying a run-as security role in the deployment descriptor. The deployer then chooses a user from the execution environment under whose security principal the bean executes. The RunAs mechanism is usually necessary for a message-driven bean because the client's message does not carry a security principal. 11.3.7 Programmatic Security APIThe EJB specification defines in the EJBContext interface two methods that allow an invoked enterprise bean method to obtain security information about the method's caller:
The application developer or deployer can use these two security methods in the enterprise bean application logic to perform programmatically the authorization checks that are not easily done using the declarative security mechanism. For example, let's assume that the deployer of the PayrollEJB bean wants to allow each employee to access only his or her personal salary information via the getSalary method. In addition, the deployer wants to allow the entire payroll staff to access the salaries of all employees. Note that this authentication rule cannot be expressed using the declarative security mechanism. One possible way for the deployer to implement this authentication rule is to subclass the generic PayrollBean class, which has no security checks, and produce a StarPayrollBean class that includes the desired authentication check (Code Example 11.1): Code Example 11.1 Adding Authentication Checks to a Beanpublic class StarPayrollBean extends PayrollBean { Session sessionCtx; public double getSalary(int emplNumber) { Principal callerPrincipal = sessionCtx.getCallerPrincipal(); int callerEmplNumber = Integer.parseInt(callerPrincipal.getName()); if (sessionCtx.isCallerInRole("employee") && emplNumber == callerEmplNumber) || sessionCtx.isCallerInRole("payroll-dept")) { // Allow access. return super.getSalary(emplNumber); } else { throw new SecurityException("access to salary denied"); } } public void setSessionContext(SessionContext sc) { sessionCtx = sc; super.setSessionContext(sc); } } Note that StarPayrollBean uses the getCallerPrincipal method to obtain the caller's principal and then invokes the isCallerInRole method to check the caller's role before allowing access to the salary data. If the caller's role is that of an employee and the caller's employee number matches that of the salary record or the caller is part of the payroll department, the method permits access to the salary data; otherwise, it throws a security exception. In our example, we illustrated how a deployer can use subclassing to add a fine-grained authorization rule to a method. Of course, the developer of the PayrollBean bean could implement this authorization rule directly in the PayrollBean class, but the PayrollBean bean would become less reusable as a result because the format of the caller's principal returned by the getCallerPrincipal method depends on the application server and security mechanisms used in an enterprise. 11.3.8 Example Security ApplicationThe example application from Chapter 8 uses the declarative security mechanism. In this section, we discuss the security views of each of the providers of the application's parts the Wombat ISV and Star Enterprise. Wombat Developer's View of SecurityThe Wombat application developer has no knowledge of the security environment at the customer site: Star Enterprise. For example, the developer does not know the user accounts or user groups defined by the system administrator at Star Enterprise. To handle this situation, an ISV analyzes its application from a security point of view, defining intended use cases of the various application parts and defining security roles for each case. Essentially, the developer details the functions that application users will perform and then defines distinct roles permitted to perform particular sets of functions. Wombat defines two security roles that summarize the intended use cases of the Wombat application's parts from the security point of view:
After identifying the security roles for the enterprise beans, the Wombat developer defines the method permissions that each security role must have to perform its application use cases. The method permissions are depicted in Table 11.1. The employee security role needs to have access to all the methods of EnrollmentEJB, which in turn needs to have access to the methods of SelectionEJB, WrapperPlanEJB, and EmployeeEJB. The reason is that the implementation of EnrollmentEJB calls these methods that is, these methods are called from the EnrollmentBean class. Some enterprise bean methods, such as the create and remove methods of the EmployeeEJB's local home interface, are not associated with a security role. What does this mean? Wombat designed the interfaces of its enterprise beans to be used by other applications, not just by the enrollment application. The enrollment application does not use some of the methods, and these methods are not associated with a security role. How should the deployer treat these methods? Unless the deployer wants to enable other applications to access to these methods, the deployer should simply disallow access to these methods by marking them as uncallable.
Star Enterprise's View of Security RolesStar Enterprise's IT department developed some enterprise beans and integrated them with Wombat's Benefits Enrollment application. The security settings for the beans developed by Star Enterprise are as follows:
|