Security

All the annotations in this section belong to the Common Annotations specification. The EJB specification defines their expected behaviour implements these annotations in a way that they are honoured at runtime.

@DeclareRoles

As the name itself indicates, this Class level annotation is used to declare a list of roles available for use by an EJB. Specifically, it comes into picture when programmatic (API based) authorization check is initiated by the javax.ejb.EJBContext.isCallerInRole(String role) method

package ejbap.security;

import java.math.BigDecimal;
import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;

@DeclareRoles({"admin"})
@Stateless
public class AdminOperationsFacade {
    @Resource
    private EJBContext ejbCtx;

    public void updateSalary(BigDecimal salary){
        System.out.println("Is Admin ? "+ ejbCtx.isCallerInRole("admin"));
        //business logic...
    }
}

@RolesAllowed

This annotation can be used on classes, individual methods or both. It specifies one or more roles which are permitted to invoke bean methods. In case the annotation is used on both class and individual methods of the bean class, the method level annotation takes precedence

@PermitAll

@PermitAll can be used on both class and individual methods. If applied on a class, this annotation allows all its methods to be executed without any restrictions unless a method is explicitly annotated using @RolesAllowed

@DenyAll

This can be applied on a class or on specific methods. It instructs the container to forbid execution of the particular method guarded by this annotation. Please note that the method can still be used internally within the bean class

package ejbap.security;

import java.math.BigDecimal;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;

@Stateless
@DeclareRoles({"Administrators", "HR , Managers"})
@RolesAllowed({"Managers"})
public class EmployeeManagementFacade {

    @RolesAllowed({"HR"})
    public void updateSalary(BigDecimal salary){
        //only 'HR'
    }

    public void updateAppraisalDetails(String details){
        //only 'Managers'
    }

    @PermitAll
    public String getEmailAddress(String empID){
        //no authorization needed
        String address = null;
        //logic..
        return address;
    }

    @DenyAll
    public void deleteEmployeeRecord(int id){
        //external access blocked
    }
}

@RunAs

The use of this annotation helps impersonate a user identity (on purpose) i.e. it allows a bean method to be invoked via a specific role by explicitly mentioning the same. This annotation can only be used on a class and is implicitly enforced on all the its methods

Additional (Java EE) security concepts

A detailed discussion of Java EE security topics is out of scope of this book. This section briefly covers whats needed to make better sense of these annotations

Are these only for EJBs ?

These annotations allow EJBs to be secured declaratively, but their usage is not restricted to them. They can be used to protect Web Components as well (deployed within a Web Container) e.g. Servlets, RESTful endpoints etc (basically, any component with a URL which can be accessed over HTTP can be protected)

Authentication or Authorization ?

It is extremely important to understand that these annotations are meant for Authorization only i.e. they just check whether the calling entity (principal) has the privileges to execute a specific method. The actual Authentication is carried out by a different process (generally using Security Realms configured within the application server) and usually happens at the Web layer (enforced by the Web Container)

Principal/Identity Propagation

Authorization (in the EJB container) is not possible without prior authentication in the Web container. This is because, the privileges (equivalent to groups in the security realm e.g. database, LDAP etc.) of the authentication identity (principal) are propagated from the Web to the EJB container which then enforces authorization checks using the annotations. This principal can be ignored/manipulated only when the @RunAs annotation is leveraged

Is there an alternative to annotations ?

Yes. ejb-jar.xml and web.xml (deployment descriptors for EJB and Web containers respectively). Both offer the same (declarative) model for protecting resources. While ejb-jar.xml is only for authorization related details, web.xml contains both authentication & authorization configurations. In fact, there might be times when it is preferable to use these descriptors along with the annotations.

Coming up next

We shall dive into transaction related annotations ...

Last updated