Because not all security policies can be expressed declaratively, the EJB architecture also provides a simple programmatic interface that the Bean programmer can use to access the security context from the business methods.
The javax.ejb.EJBContext interface provides two methods that allow the bean programmer to access security information about the Enterprise Bean's caller.
public interface javax.ejb.EJBContext { ... // // The following two methods allow the EJB class // to access security information // java.security.Principal getCallerPrincipal() ; boolean isCallerInRole (String roleName) ; ... } |
The purpose of the getCallerPrincipal() method is to allow the Enterprise Bean methods to obtain the current caller principal's name. The methods might, for example, use the name as a key to access information in a database.
An Enterprise Bean can invoke the getCallerPrincipal() method to obtain a java.security.Principal interface representing the current caller. The Enterprise Bean can then obtain the distinguished name of the caller principal using the getName() method of the java.security.Principal interface.
The main purpose of the isCallerInRole(String roleName) method is to allow the Bean programmer to code the security checks that cannot be easily defined declaratively in the deployment descriptor using method permissions. Such a check might impose a role-based limit on a request, or it might depend on information stored in the database.
The Enterprise Bean code uses the isCallerInRole(String roleName) method to test whether the current caller has been assigned to a given security role or not. Security roles are defined by the application assembler in the deployment descriptor and are assigned to principals by the deployer.
The Bean programmer must declare in the security-role-ref elements of the deployment descriptor all the security role names used in the Enterprise Bean code. Declaring the security roles' references in the code allows the application assembler or deployer to link the names of the security roles used in the code to the actual security roles defined for an assembled application through the security-role elements.
... <enterprise-beans> ... <session> <ejb-name>Op</ejb-name> <ejb-class>sb.OpBean</ejb-class> ... <security-role-ref> <role-name>role1</role-name> </security-role-ref> ... </session> ... </enterprise-beans> ... |
The deployment descriptor in this example indicates that the Enterprise Bean Op makes the security checks using isCallerInRole("role1") in at least one of its business methods.
If the security-role elements have been defined in the deployment descriptor, all the security role references declared in the security-role-ref elements must be linked to the security roles defined in the security-role elements.
The following deployment descriptor example shows how to link the security role references named role1 to the security role named tomcat.
... <enterprise-beans> ... <session> <ejb-name>Op</ejb-name> <ejb-class>sb.OpBean</ejb-class> ... <security-role-ref> <role-name>role1</role-name> <role-link>tomcat</role-link> </security-role-ref> ... </session> ... </enterprise-beans> ... |
In summary, the role names used in the EJB code (in the isCallerInRole method) are, in fact, references to actual security roles, which makes the EJB code independent of the security configuration described in the deployment descriptor. The programmer makes these role references available to the Bean deployer or application assembler via the security-role-ref elements included in the session or entity elements of the deployment descriptor. Then, the Bean deployer or application assembler must map the security roles defined in the deployment descriptor to the "specific" roles of the target operational environment (for example, groups on Unix systems). However, this last mapping step is not currently available in JOnAS.