[[_jboss_adapter]]

ifeval::[{project_community}==true]
==== JBoss EAP/Wildfly Adapter
endif::[]
ifeval::[{project_product}==true]
==== JBoss EAP Adapter
endif::[]

ifeval::[{project_community}==true]
To be able to secure WAR apps deployed on JBoss EAP, WildFly or JBoss AS, you must install and configure the
{project_name} adapter subsystem. You then have two options to secure your WARs.
endif::[]
ifeval::[{project_product}==true]
To be able to secure WAR apps deployed on JBoss EAP, you must install and configure the
{project_name} adapter subsystem. You then have two options to secure your WARs.
endif::[]

You can provide an adapter config file in your WAR and change the auth-method to KEYCLOAK within web.xml.

Alternatively, you don't have to modify your WAR at all and you can secure it via the {project_name} adapter subsystem configuration in `standalone.xml`.
Both methods are described in this section.

[[_jboss_adapter_installation]]
===== Installing the adapter

Adapters are available as a separate archive depending on what server version you are using.

ifeval::[{project_community}==true]
Install on Wildfly 9, 10 or 11:

[source, subs="attributes"]
----
$ cd $WILDFLY_HOME
$ unzip keycloak-wildfly-adapter-dist-{project_version}.zip
----

Install on Wildfly 8:

[source, subs="attributes"]
----
$ cd $WILDFLY_HOME
$ unzip keycloak-wf8-adapter-dist-{project_version}.zip
----

Install on JBoss EAP 7:

[source, subs="attributes"]
----
$ cd $EAP_HOME
$ unzip keycloak-eap7-adapter-dist-{project_version}.zip
----

Install on JBoss EAP 6:

[source, subs="attributes"]
----
$ cd $EAP_HOME
$ unzip keycloak-eap6-adapter-dist-{project_version}.zip
----

Install on JBoss AS 7.1:

[source, subs="attributes"]
----
$ cd $JBOSS_HOME
$ unzip keycloak-as7-adapter-dist-{project_version}.zip
----
endif::[]

ifeval::[{project_product}==true]

Install on JBoss EAP 7:

You can install the EAP 7 adapters either by unzipping a ZIP file, or by using an RPM.

Install the EAP 7 Adapters from a ZIP File:

[source, subs="attributes"]
----
$ cd $EAP_HOME
$ unzip rh-sso-{project_version}-eap7-adapter.zip
----

Install the EAP 7 Adapters from an RPM:

NOTE: With Red Hat Enterprise Linux 7, the term channel was replaced with the term repository. In these instructions only the term repository is used.

You must subscribe to the JBoss EAP 7.0 repository before you can install the EAP 7 adapters from an RPM.

.Prerequisites

. Ensure that your Red Hat Enterprise Linux system is registered to your account using Red Hat Subscription Manager. For more information see the link:https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html-single/quick_registration_for_rhel/index[Red Hat Subscription Management documentation].

. If you are already subscribed to another JBoss EAP repository, you must unsubscribe from that repository first.

Using Red Hat Subscription Manager, subscribe to the JBoss EAP 7.0 repository using the following command. Replace <RHEL_VERSION> with either 6 or 7 depending on your Red Hat Enterprise Linux version.

----
$ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
----

Install the EAP 7 adapters for OIDC using the following command:

----
$ sudo yum install eap7-keycloak-adapter
----

Install the EAP 7 adapters for SAML using the following command:

----
$ sudo yum install eap7-keycloak-saml-adapter
----

NOTE: The default EAP_HOME path for the RPM installation is /opt/rh/eap7/root/usr/share/wildfly.

Run the appropriate module installation script.

For the OIDC module, enter the following command:

----
$ {EAP_HOME}/bin/jboss-cli.sh -c --file=${EAP_HOME}/bin/adapter-install.cli
----

For the SAML module, enter the following command:

----
$ {EAP_HOME}/bin/jboss-cli.sh -c --file=${EAP_HOME}/bin/adapter-install-saml.cli
----

Your installation is complete.

Install on JBoss EAP 6:

You can install the EAP 6 adapters either by unzipping a ZIP file, or by using an RPM.

Install the EAP 6 Adapters from a ZIP File:

[source, subs="attributes"]
----
$ cd $EAP_HOME
$ unzip rh-sso-{project_version}-eap6-adapter.zip
----

Install the EAP 6 Adapters from an RPM:

NOTE: With Red Hat Enterprise Linux 7, the term channel was replaced with the term repository. In these instructions only the term repository is used.

You must subscribe to the JBoss EAP 6.0 repository before you can install the EAP 6 adapters from an RPM.

.Prerequisites

. Ensure that your Red Hat Enterprise Linux system is registered to your account using Red Hat Subscription Manager. For more information see the link:https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html-single/quick_registration_for_rhel/index[Red Hat Subscription Management documentation].

. If you are already subscribed to another JBoss EAP repository, you must unsubscribe from that repository first.

Using Red Hat Subscription Manager, subscribe to the JBoss EAP 6.0 repository using the following command. Replace <RHEL_VERSION> with either 6 or 7 depending on your Red Hat Enterprise Linux version.

----
$ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
----

Install the EAP 6 adapters for OIDC using the following command:

----
$ sudo yum install eap6-keycloak-adapter
----

Install the EAP 6 adapters for SAML using the following command:

----
$ sudo yum install eap6-keycloak-saml-adapter
----

NOTE: The default EAP_HOME path for the RPM installation is /opt/rh/eap6/root/usr/share/wildfly.

Run the appropriate module installation script.

For the OIDC module, enter the following command:

----
$ {EAP_HOME}/bin/jboss-cli.sh -c --file=${EAP_HOME}/bin/adapter-install.cli
----

For the SAML module, enter the following command:

----
$ {EAP_HOME}/bin/jboss-cli.sh -c --file=${EAP_HOME}/bin/adapter-install-saml.cli
----

Your installation is complete.
endif::[]

This ZIP archive contains JBoss Modules specific to the {project_name} adapter. It also contains JBoss CLI scripts to configure the adapter subsystem.

To configure the adapter subsystem if the server is not running execute:

ifeval::[{project_community}==true]
.Wildfly 11
[source]
----
$ ./bin/jboss-cli.sh --file=adapter-elytron-install-offline.cli
----
endif::[]

.Any other server but Wildfly 11
[source]
----
$ ./bin/jboss-cli.sh --file=adapter-install-offline.cli
----

NOTE: The offline script is not available for JBoss EAP 6

Alternatively, if the server is running execute:

ifeval::[{project_community}==true]
.Wildfly 11
[source]
----
$ ./bin/jboss-cli.sh --file=adapter-elytron-install.cli
----
endif::[]

.Any other server but Wildfly 11
[source]
----
$ ./bin/jboss-cli.sh --file=adapter-install.cli
----

===== JBoss SSO

{appserver_name} has built-in support for single sign-on for web applications deployed to the same {appserver_name}
instance. This should not be enabled when using {project_name}.

===== Required Per WAR Configuration

This section describes how to secure a WAR directly by adding configuration and editing files within your WAR package.

The first thing you must do is create a `keycloak.json` adapter configuration file within the `WEB-INF` directory of your WAR.

The format of this configuration file is described in the <<_java_adapter_config,Java adapter configuration>> section.

Next you must set the `auth-method` to `KEYCLOAK` in `web.xml`.
You also have to use standard servlet security to specify role-base constraints on your URLs.

Here's an example:

[source,xml]
----

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">

    <module-name>application</module-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Admins</web-resource-name>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customers</web-resource-name>
            <url-pattern>/customers/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>KEYCLOAK</auth-method>
        <realm-name>this is ignored currently</realm-name>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>
----

===== Securing WARs via Adapter Subsystem

You do not have to modify your WAR to secure it with {project_name}. Instead you can externally secure it via the {project_name} Adapter Subsystem.
While you don't have to specify KEYCLOAK as an `auth-method`, you still have to define the `security-constraints` in `web.xml`.
You do not, however, have to create a `WEB-INF/keycloak.json` file.
This metadata is instead defined within server configuration (i.e. `standalone.xml`) in the {project_name} subsystem definition.

[source,xml]
----
<extensions>
  <extension module="org.keycloak.keycloak-adapter-subsystem"/>
</extensions>

<profile>
  <subsystem xmlns="urn:jboss:domain:keycloak:1.1">
     <secure-deployment name="WAR MODULE NAME.war">
        <realm>demo</realm>
        <auth-server-url>http://localhost:8081/auth</auth-server-url>
        <ssl-required>external</ssl-required>
        <resource>customer-portal</resource>
        <credential name="secret">password</credential>
     </secure-deployment>
  </subsystem>
</profile>
----

The `secure-deployment` `name` attribute identifies the WAR you want to secure.
Its value is the `module-name` defined in `web.xml` with `.war` appended. The rest of the configuration corresponds pretty much one to one with the `keycloak.json` configuration options defined in <<_java_adapter_config,Java adapter configuration>>.

The exception is the `credential` element.

To make it easier for you, you can go to the {project_name} Administration Console and go to the Client/Installation tab of the application this WAR is aligned with.
It provides an example XML file you can cut and paste.

If you have multiple deployments secured by the same realm you can share the realm configuration in a separate element. For example:

[source,xml]
----
<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
    <realm name="demo">
        <auth-server-url>http://localhost:8080/auth</auth-server-url>
        <ssl-required>external</ssl-required>
    </realm>
    <secure-deployment name="customer-portal.war">
        <realm>demo</realm>
        <resource>customer-portal</resource>
        <credential name="secret">password</credential>
    </secure-deployment>
    <secure-deployment name="product-portal.war">
        <realm>demo</realm>
        <resource>product-portal</resource>
        <credential name="secret">password</credential>
    </secure-deployment>
    <secure-deployment name="database.war">
        <realm>demo</realm>
        <resource>database-service</resource>
        <bearer-only>true</bearer-only>
    </secure-deployment>
</subsystem>
----


===== Security Domain

To propagate the security context to the EJB tier you need to configure it to use the "keycloak" security domain. This
can be achieved with the @SecurityDomain annotation:

[source]
----

import org.jboss.ejb3.annotation.SecurityDomain;
...

@Stateless
@SecurityDomain("keycloak")
public class CustomerService {

    @RolesAllowed("user")
    public List<String> getCustomers() {
        return db.getCustomers();
    }
}
----