include::../shared-doc/attributes.adoc[]

= ejb-security:  Using Java EE Declarative Security to Control Access
:author: Sherif F. Makary, Stefan Guilhen
:level: Intermediate
:technologies: EJB, Security

[abstract]
The `ejb-security` quickstart demonstrates the use of Java EE declarative security to control access to EJBs in {productName}.

:standalone-server-type: default
:archiveType: jar
:includes-cli-scripts:
:restoreScriptName: restore-configuration.cli
:app-user-groups: guest

== What is it?

The `ejb-security` quickstart demonstrates the use of Java EE declarative security to control access to EJBs in {productNameFull}.

This quickstart takes the following steps to implement EJB security:

. Add an `application-security-domain` mapping in the `ejb3` subsystem to enable Elytron security for the `SecuredEJB`.
. Add the `@SecurityDomain(&quot;other&quot;)` security annotation to the EJB declaration to tell the EJB container to apply authorization to this EJB.
. Add the `@RolesAllowed({ &quot;guest&quot; })` annotation to the EJB declaration to authorize access only to users with `guest` role access rights.
. Add the `@RolesAllowed({ &quot;admin&quot; })` annotation to the administrative method in the `SecuredEJB` to authorize access only
to users with `admin` role access rights.
. Add an application user with `guest` role access rights to the EJB. This quickstart defines a user `quickstartUser` with
password `quickstartPwd1!` in the `guest` role. The `guest` role matches the allowed user role defined in the `@RolesAllowed`
annotation in the EJB but it should not be granted access to the administrative method annotated with `RolesAllowed({&quot;admin&quot;})`.

// System Requirements
include::../shared-doc/system-requirements.adoc[leveloffset=+1]
// Use of {jbossHomeName}
include::../shared-doc/use-of-jboss-home-name.adoc[leveloffset=+1]
// Add the Authorized Application User
include::../shared-doc/add-application-user.adoc[leveloffset=+1]
// Back Up the {productName} Standalone Server Configuration
include::../shared-doc/back-up-server-standalone-configuration.adoc[leveloffset=+1]
// Start the {productName} Standalone Server
include::../shared-doc/start-the-standalone-server.adoc[leveloffset=+1]

[[configure_the_server]]
== Configure the Server

You configure the security domain by running JBoss CLI commands. For your convenience, this quickstart batches the commands into a `configure-elytron.cli` script provided in the root directory of this quickstart.

. Before you begin, make sure you do the following:

* xref:back_up_standalone_server_configuration[Back up the {productName} standalone server configuration] as described above.
* xref:start_the_eap_standalone_server[Start the {productName} server with the standalone default profile] as described above.

. Review the `configure-elytron.cli` file in the root of this quickstart directory. This script adds the configuration that enables Elytron security for the quickstart components. Comments in the script describe the purpose of each block of commands.
. Open a new terminal, navigate to the root directory of this quickstart, and run the following command, replacing `__{jbossHomeName}__` with the path to your server:
+
[source,subs="+quotes,attributes+",options="nowrap"]
----
$ __{jbossHomeName}__/bin/jboss-cli.sh --connect --file=configure-elytron.cli
----
+
NOTE: For Windows, use the `__{jbossHomeName}__\bin\jboss-cli.bat` script.
+

You should see the following result when you run the script:
+
[source,options="nowrap"]
----
The batch executed successfully
process-state: reload-required
----

. Stop the {productName} server.

== Review the Modified Server Configuration

After stopping the server, open the `__{jbossHomeName}__/standalone/configuration/standalone.xml` file and review the changes.

. The following `application-security-domain` mapping was added to the `ejb3` subsystem:
+
[source,xml,options="nowrap"]
----
<application-security-domains>
    <application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
----
+
The `application-security-domain` enables Elytron security for the quickstart EJBs. It maps the `other` security domain that is set in the EJBs using the Java annotation `@SecurityDomain("other")` to the Elytron `ApplicationDomain` that is responsible for authenticating and authorizing access to the EJBs.

. The `http-remoting-connector` in the `remoting` subsystem was updated to use the `application-sasl-authentication` factory:
+
[source,xml,options="nowrap"]
----
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm" sasl-authentication-factory="application-sasl-authentication"/>
----
+
This configuration allows the identity that was established at the connection level to be propagated to the components.

// Build and Deploy the Quickstart
include::../shared-doc/build-and-deploy-the-quickstart.adoc[leveloffset=+1]


== Run the Client

Before you run the client, make sure you have already successfully deployed the EJBs to the server in the previous step and that your terminal is still in the root directory of this quickstart.

Type this command to execute the client:

[source,options="nowrap"]
----
$ mvn exec:exec
----

== Investigate the Console Output

When you run the `mvn exec:exec` command, you see the following output. Note there may be other log messages interspersed between these messages.

[source,options="nowrap"]
----
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Successfully called secured bean, caller principal quickstartUser

Principal has admin permission: false

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
----

The username and credentials used to establish the connection to the application server are configured in the `wildfly-config.xml` file. As expected, the `quickstartUser` was able to invoke the method available for the `guest`role, but not the administrative method that requires the `admin` role.

[NOTE]
====
You should also see the following `EJBAccessException` printed in the server log, followed by a stack trace. This is to be expected because the user does not have the correct permissions to access the EJB.

[source,options="nowrap"]
----
ERROR [org.jboss.as.ejb3.invocation] (default task-38) WFLYEJB0034: EJB Invocation failed on component SecuredEJB for method public abstract boolean org.jboss.as.quickstarts.ejb_security.SecuredEJBRemote.administrativeMethod(): javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public abstract boolean org.jboss.as.quickstarts.ejb_security.SecuredEJBRemote.administrativeMethod() of bean: SecuredEJB is not allowed
----
====

[[update_the_application_user_role]]
== Update the Authorized Application User Role

As an exercise, you can rerun the `add-user` script described in the xref:add_the_application_user[Add the Authorized Application User] section, but this time grant the `quickstartUser` the `admin` role as follows:

[source,subs="+quotes,attributes+",options="nowrap"]
----
$ __{jbossHomeName}__/bin/add-user.sh -a -u 'quickstartUser' -p 'quickstartPwd1!' -g 'guest,admin'
----

NOTE: For Windows, use the `__{jbossHomeName}__\bin\add-user.bat` scripts.

After you update the `quickstartUser` user role, you must restart the server for it to take effect. Running the client again should immediately reflect the new permission level of the user:

[source,options="nowrap"]
----
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Successfully called secured bean, caller principal quickstartUser

Principal has admin permission: true

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
----

// Undeploy the Quickstart
include::../shared-doc/undeploy-the-quickstart.adoc[leveloffset=+1]
// Restore the {productName} Standalone Server Configuration
include::../shared-doc/restore-standalone-server-configuration.adoc[leveloffset=+1]

// Additional information about this script
This script reverts the changes made to the `ejb3` and `undertow` subsystems. You should see the following result when you run the script.

[source,options="nowrap"]
----
The batch executed successfully
process-state: reload-required
----

// Restore the {productName} Standalone Server Configuration Manually
include::../shared-doc/restore-standalone-server-configuration-manual.adoc[leveloffset=+2]
// Run the Quickstart in Red Hat Developer Studio or Eclipse
include::../shared-doc/run-the-quickstart-in-jboss-developer-studio.adoc[leveloffset=+1]

// Additional Red Hat Developer Studio instructions
. Make sure you xref:add_the_application_user[Add the authorized application user] as described above.
. Make sure you configure the server by running the JBoss CLI script as described above under xref:configure_the_server[Configure the Server].
. To deploy the server project, right-click on the *{artifactId}* project and choose *Run As* –> *Maven build*. Enter *clean package wildfly:deploy* for the *Goals* and click *Run*. This deploys the `{artifactId}` JAR to the {productName} server.
. Right-click on the *{artifactId}* project and choose *Run As* –> *Run Configurations*. Enter *exec:exec* for the *Goals*, and then click *Run*.
. Review the output in the console window. You should see the same results as when running Maven in the command line.
. To undeploy the project, right-click on the *{artifactId}* project and choose *Run As* –> *Run Configurations*. Enter `wildfly:undeploy` for the *Goals* and click *Run*.
. Make sure you xref:restore_the_server_configuration[restore the server configuration] when you have completed testing this quickstart.

// Debug the Application
include::../shared-doc/debug-the-application.adoc[leveloffset=+1]
