# Security

All the annotations in this section belong to the [Common Annotations specification](https://jcp.org/en/jsr/detail?id=250). 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 ...


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abhishek-gupta.gitbook.io/ejb-annotations-primer/security.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
