Develop with programmatic APIs for EJB applications
Use this topic to programmatically secure your EJB applications.
Programmatic security is used by security-aware applications when declarative security alone is not sufficient to express the security model of the application. The javax.ejb.EJBContext application programming interface (API) provides two methods whereby the bean provider can access security information about the enterprise bean caller.
- IsCallerInRole(String rolename): Returns true if the bean caller is granted the security role specified by role name. If the caller is not granted the specified role, or if the caller is not authenticated, it returns false. If the specified role is granted Everyone access, it always returns true.
- getCallerPrincipal: Return the java.security. Principal object containing the bean caller name. If the caller is not authenticated, it returns a principal containing an unauthorized name.
We can enable a login module to indicate which principal class is returned by these calls.
When the isCallerInRole method is used, declare a security-role-ref element in the deployment descriptor with a role-name that is subelement containing the role name that is passed to this method. Because actual roles are created during the assembly stage of the application, we can use a logical role as the role name and provide enough hints to the assembler in the description of the security-role-ref element to link that role to an actual role. During assembly, the assembler creates a role-link subelement to link the role-name to the actual role. Creation of a security-role-ref element is possible if an assembly tool such as Rational Application Developer is used. We also can create the security-role-ref element during the assembly stage using an assembly tool.
Tasks
- Add the required security methods in the EJB module code.
- Create a security-role-ref element with a role-name field for all the role names used in the isCallerInRole method. If a security-role-ref element is not created during development, make sure that it is created during the assembly stage.
Performing the previous steps result in a programmatically secured EJB application.
Example
Hardcoding security policies in applications are strongly discouraged. The Java Platform, Enterprise Edition (Java EE) security model capabilities of declaratively specifying security policies is encouraged wherever possible. Use these APIs to develop security-aware EJB applications.Use Java EE security model capabilities to specify security policies declaratively is useful when an EJB application wants to access external resources and wants to control the access to these external resources using its own authorization table (external-resource to user mapping). In this case, use the getCallerPrincipal method to get the caller identity and then the application can consult its own authorization table to perform authorization. The caller identification also can help retrieve the corresponding user information from an external source, such as database or from another enterprise bean. Use the isCallerInRole method in a similar way.
After development, we can create a security-role-ref element:
<security-role-ref> <description>Provide hints to assembler for linking this role-name to actual role here<\description> <role-name>Mgr<\role-name> </security-role-ref>During assembly, the assembler creates a role-link element:
<security-role-ref> <description>Hints provided by developer to map role-name to role-link</description> <role-name>Mgr</role-name> <role-link>Manager</role-link> </security-role-ref>We can add programmatic EJB component security methods for example isCallerInRole and getCallerPrincipal, inside any business methods of an enterprise bean. The following example of programmatic security APIs includes a session bean:
public class aSessionBean implements SessionBean { ..... // SessionContext extends EJBContext. If it is entity bean use EntityContext javax.ejb.SessionContext context; // The following method will be called by the EJB container // automatically public void setSessionContext(javax.ejb.SessionContext ctx) { context = ctx; // save the session bean's context } .... private void aBusinessMethod() { .... // Get bean's caller using getCallerPrincipal() java.security.Principal principal = context.getCallerPrincipal(); String callerId= principal.getName(); // Check if bean's caller is granted Mgr role boolean isMgr = context.isCallerInRole("Mgr"); // Use the above information in any way as needed by the //application .... } .... }When developing EJB 3.x modules, the value of the rolename argument in isCallerInRole method can be defined using Java annotations instead of declaring a security-role-ref element in the deployment descriptor.
@javax.annotation.security.DeclareRoles("Mgr") @Stateless // annotation is used to indicate a session bean public class aSessionBean implements MyBusinessInterface { //we don't have to extend sessionbean interface ..... // SessionContext extends EJBContext. In EJB 3.0 use Resource annotation to inject context @Resource javax.ejb.SessionContext context; } .... private void aBusinessMethod() { .... // Get bean's caller using getCallerPrincipal() java.security.Principal principal = context.getCallerPrincipal(); String callerId= principal.getName(); // Check if bean's caller is granted Mgr role boolean isMgr = context.isCallerInRole("Mgr"); // Use the above information in any way as needed by the //application .... } .... }
What to do next
After developing an application, use an assembly tool to create roles and to link the actual roles to role names in the security-role-ref elements. See the information about securing web applications using an assembly tool.
Subtopics
- Example: Enterprise bean application code
The following EJB component example illustrates the use of the isCallerInRole and the getCallerPrincipal methods in an EJB module.
Secure enterprise bean applications Security: Resources for learning