[[Securing_Jakarta_Enterprise_Beans]]
= Securing Jakarta Enterprise Beans

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

The Jakarta EE spec specifies certain annotations (like @RolesAllowed,
@PermitAll, @DenyAll) which can be used on Jakarta Enterprise Beans implementation classes
and/or the business method implementations of the beans. Like with all
other configurations, these security related configurations can also be
done via the deployment descriptor (ejb-jar.xml). We _won't_ be going
into the details of Jakarta EE specific annotations/deployment descriptor
configurations in this chapter but instead will be looking at the vendor
specific extensions to the security configurations.

== Security Domain

The Jakarta EE spec doesn't mandate a specific way to configure security
domain for a bean. It leaves it to the vendor implementations to allow
such configurations, the way they wish. In WildFly {wildflyVersion}, the use of
`@org.jboss.ejb3.annotation.SecurityDomain` annotation allows the
developer to configure the security domain for a bean. Here's an
example:

[source,java,options="nowrap"]
----
import org.jboss.ejb3.annotation.SecurityDomain;

import jakarta.ejb.Stateless;

@Stateless
@SecurityDomain("other")
﻿public class MyBean ...
{
   ...
}
----

The use of @SecurityDomain annotation lets the developer to point the
container to the name of the security domain which is configured in the
Jakarta Enterprise Beans 3 subsystem in the standalone/domain configuration. The configuration
of the security domain in the Jakarta Enterprise Beans 3 subsystem is out of the scope of this
chapter.

An alternate way of configuring a security domain, instead of using
annotation, is to use jboss-ejb3.xml deployment descriptor. Here's an
example of how the configuration will look like:

[source,xml,options="nowrap"]
----
<?xml version="1.0" encoding="UTF-8"?>
<jboss:jboss
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:s="urn:security:1.1"
         xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-spec-2_0.xsd"
         version="3.1" impl-version="2.0">

    <assembly-descriptor>
        <s:security>
   <!-- Even wildcard * is supported -->
            <ejb-name>MyBean</ejb-name>
            <!-- Name of the security domain which is configured in the EJB3 subsystem -->
            <s:security-domain>other</s:security-domain>
        </s:security>
    </assembly-descriptor>
</jboss:jboss>
----

As you can see we use the security-domain element to configure the
security domain.

[IMPORTANT]

The jboss-ejb3.xml is expected to be placed in the .jar/META-INF folder
of a .jar deployment or .war/WEB-INF folder of a .war deployment.

[[absence-of-security-domain-configuration-but-presence-of-other-security-metadata]]
== Absence of security domain configuration but presence of other security metadata

Let's consider the following example bean:

[source,java,options="nowrap"]
----
@Stateless
public class FooBean {

 @RolesAllowed("bar")
 public void doSomething() {
  ..
 }
...
}
----

As you can see the `doSomething` method is configured to be accessible
for users with role "bar". However, the bean isn't configured for any
specific security domain. Prior to WildFly {wildflyVersion}, the absence of an
explicitly configured security domain on the bean would leave the bean
unsecured, which meant that even if the `doSomething` method was
configured with `@RolesAllowed("bar")` anyone even without the "bar"
role could invoke on the bean.

In WildFly {wildflyVersion}, the presence of any security metadata (like @RolesAllowed,
@PermitAll, @DenyAll, @RunAs, @RunAsPrincipal) on the bean or any
business method of the bean, makes the bean secure, even in the absence
of an explicitly configured security domain. In such cases, the security
domain name is default to "other". Users can explicitly configure an
security domain for the bean if they want to using either the annotation
or deployment descriptor approach explained earlier.

[[access-to-methods-without-explicit-security-metadata-on-a-secured-bean]]
== Access to methods without explicit security metadata, on a secured bean

Consider this example bean:

[source,java,options="nowrap"]
----
@Stateless
public class FooBean {

 @RolesAllowed("bar")
 public void doSomething() {
  ..
 }


 public void helloWorld() {
  ...
    }
}
----

As you can see the `doSomething` method is marked for access for only
users with role "bar". That enables security on the bean (with security
domain defaulted to "other"). However, notice that the method
`helloWorld` doesn't have any specific security configurations.

In WildFly {wildflyVersion}, such methods which have no explicit security
configurations, in a secured bean, will be treated similar to a method
with `@DenyAll` configuration. What that means is, no one is allowed
access to the `helloWorld` method. This behaviour can be controlled via
the jboss-ejb3.xml deployment descriptor at a per bean level or a per
deployment level as follows:

[source,xml,options="nowrap"]
----
<?xml version="1.0" encoding="UTF-8"?>
<jboss:jboss
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:s="urn:security:1.1"
        xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-spec-2_0.xsd"
        version="3.1" impl-version="2.0">

    <assembly-descriptor>
        <s:security>
   <!-- Even wildcard * is supported where * is equivalent to all EJBs in the deployment -->
            <ejb-name>FooBean</ejb-name>
            <s:missing-method-permissions-deny-access>false</s:missing-method-permissions-deny-access>
        </s:security>
    </assembly-descriptor>
</jboss:jboss>
----

Notice the use of `<missing-method-permissions-deny-access>` element.
The value for this element can either be true or false. If this element
isn't configured then it is equivalent to a value of true i.e. no one is
allowed access to methods, which have no explicit security
configurations, on secured beans. Setting this to false allows access to
such methods for all users i.e. the behaviour will be switched to be
similar to `@PermitAll`.

This behaviour can also be configured at the `ejb3` subsystem level so
that it applies to all Jakarta Enterprise Beans deployments on the server, as follows:

[source,xml,options="nowrap"]
----
<subsystem xmlns="urn:jboss:domain:ejb3:1.4">
...
    <default-missing-method-permissions-deny-access value="true"/>
...
</subsystem>
----

Again, the `default-missing-method-permissions-deny-access` element
accepts either a true or false value. A value of true makes the
behaviour similar to `@DenyAll` and a value of false makes it behave
like `@PermitAll`
