Chapter 3. Securing Users of the Server and Its Management Interfaces

3.1. User Authentication with Elytron

3.1.1. Default Configuration

By default, the JBoss EAP management interfaces are secured by the legacy core management authentication.

Example: Default Configuration

/core-service=management/management-interface=http-interface:read-resource()
{
    "outcome" => "success",
    "result" => {
        "allowed-origins" => undefined,
        "console-enabled" => true,
        "http-authentication-factory" => undefined,
        "http-upgrade" => {"enabled" => true},
        "http-upgrade-enabled" => true,
        "sasl-protocol" => "remote",
        "secure-socket-binding" => undefined,
        "security-realm" => "ManagementRealm",
        "server-name" => undefined,
        "socket-binding" => "management-http",
        "ssl-context" => undefined
    }

JBoss EAP does provide management-http-authentication and management-sasl-authentication in the elytron subsystem for securing the management interfaces as well.

To update JBoss EAP to use the default Elytron components:

  1. Set http-authentication-factory to use management-http-authentication:

    /core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=management-http-authentication)
  2. Set sasl-authentication-factory to use management-sasl-authentication:

    /core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade.sasl-authentication-factory, value=management-sasl-authentication)
  3. Undefine security-realm:

    /core-service=management/management-interface=http-interface:undefine-attribute(name=security-realm)
  4. Reload JBoss EAP for the changes to take affect:
reload

The management interfaces are now secured using the default components provided by the elytron subsystem.

3.1.1.1. Default Elytron HTTP Authentication Configuration

When you access the management interface over http, for example when using the web-based management console, JBoss EAP will use the management-http-authentication http-authentication-factory.

/subsystem=elytron/http-authentication-factory=management-http-authentication:read-resource()
{
    "outcome" => "success",
    "result" => {
        "http-server-mechanism-factory" => "global",
        "mechanism-configurations" => [{
            "mechanism-name" => "DIGEST",
            "mechanism-realm-configurations" => [{"realm-name" => "ManagementRealm"}]
        }],
        "security-domain" => "ManagementDomain"
    }
}

The management-http-authentication http-authentication-factory, is configured to use the ManagementDomain security domain.

/subsystem=elytron/security-domain=ManagementDomain:read-resource()
{
    "outcome" => "success",
    "result" => {
        "default-realm" => "ManagementRealm",
        "permission-mapper" => "default-permission-mapper",
        "post-realm-principal-transformer" => undefined,
        "pre-realm-principal-transformer" => undefined,
        "principal-decoder" => undefined,
        "realm-mapper" => undefined,
        "realms" => [
            {
                "realm" => "ManagementRealm",
                "role-decoder" => "groups-to-roles"
            },
            {
                "realm" => "local",
                "role-mapper" => "super-user-mapper"
            }
        ],
        "role-mapper" => undefined,
        "trusted-security-domains" => undefined
    }
}

The ManagementDomain security domain is backed by the ManagementRealm Elytron security realm, which is a properties-based realm.

Important

A properties-based realm is only read when the server starts. Any users added after server start, either manually or by using an add-user script, will require a server reload. This reload is accomplished by running the reload command from the management CLI.

reload
/subsystem=elytron/properties-realm=ManagementRealm:read-resource()
{
    "outcome" => "success",
    "result" => {
        "groups-attribute" => "groups",
        "groups-properties" => {
            "path" => "mgmt-groups.properties",
            "relative-to" => "jboss.server.config.dir"
        },
        "plain-text" => false,
        "users-properties" => {
            "path" => "mgmt-users.properties",
            "relative-to" => "jboss.server.config.dir"
        }
    }
}

3.1.1.2. Default Elytron Management CLI Authentication

By default, the management CLI (jboss-cli.sh) is configured to connect over remote+http.

Example: Default jboss-cli.xml

<jboss-cli xmlns="urn:jboss:cli:3.1">

    <default-protocol use-legacy-override="true">remote+http</default-protocol>

    <!-- The default controller to connect to when 'connect' command is executed w/o arguments -->
    <default-controller>
        <protocol>remote+http</protocol>
        <host>localhost</host>
        <port>9990</port>
    </default-controller>

This will establish a connection over HTTP and use HTTP upgrade to change the communication protocol to Remoting. The HTTP upgrade connection is secured in the http-upgrade section of the http-interface using a sasl-authentication-factory.

Example: Configuration with Default Components

/core-service=management/management-interface=http-interface:read-resource()
{
    "outcome" => "success",
    "result" => {
        "allowed-origins" => undefined,
        "console-enabled" => true,
        "http-authentication-factory" => "management-http-authentication",
        "http-upgrade" => {
            "enabled" => true,
            "sasl-authentication-factory" => "management-sasl-authentication"
        },
        "http-upgrade-enabled" => true,
        "sasl-protocol" => "remote",
        "secure-socket-binding" => undefined,
        "security-realm" => undefined,
        "server-name" => undefined,
        "socket-binding" => "management-http",
        "ssl-context" => undefined
    }
}

The default sasl-authentication-factory is management-sasl-authentication.

/subsystem=elytron/sasl-authentication-factory=management-sasl-authentication:read-resource()
{
    "outcome" => "success",
    "result" => {
        "mechanism-configurations" => [
            {
                "mechanism-name" => "JBOSS-LOCAL-USER",
                "realm-mapper" => "local"
            },
            {
                "mechanism-name" => "DIGEST-MD5",
                "mechanism-realm-configurations" => [{"realm-name" => "ManagementRealm"}]
            }
        ],
        "sasl-server-factory" => "configured",
        "security-domain" => "ManagementDomain"
    }
}

The management-sasl-authentication sasl-authentication-factory specifies JBOSS-LOCAL-USER and DIGEST-MD5 mechanisms.

The ManagementRealm Elytron security realm, used in DIGEST-MD5, is the same realm used in the management-http-authentication http-authentication-factory.

Example: JBOSS-LOCAL-USER Realm

/subsystem=elytron/identity-realm=local:read-resource()
{
    "outcome" => "success",
    "result" => {
        "attribute-name" => undefined,
        "attribute-values" => undefined,
        "identity" => "$local"
    }
}

The local Elytron security realm is for handling silent authentication for local users.

3.1.2. Secure the Management Interfaces with a New Identity Store

  1. Create a security domain and any supporting security realms, decoders, or mappers for your identity store.

    This process is covered in the Elytron Subsystem section of JBoss EAP How to Configure Identity Management Guide. For example, if you wanted to secure the management interfaces using a filesystem-based identity store, you would follow the steps in Configure Authentication with a Filesystem-based Identity Store.

  2. Create an http-authentication-factory or sasl-authentication-factory.

    Example: http-authentication-factory

    /subsystem=elytron/http-authentication-factory=example-http-auth:add(http-server-mechanism-factory=global, security-domain=exampleSD, mechanism-configurations=[{mechanism-name=DIGEST, mechanism-realm-configurations=[{realm-name=exampleManagementRealm}]}])

    Example: sasl-authentication-factory

    /subsystem=elytron/sasl-authentication-factory=example-sasl-auth:add(sasl-server-factory=configured, security-domain=exampleSD, mechanism-configurations=[{mechanism-name=DIGEST-MD5, mechanism-realm-configurations=[{realm-name=exampleManagementRealm}]}])

  3. Add pattern-filter to the configured configurable-sasl-server-factory.

    Example: Add GSSAPI to the Configured configurable-sasl-server-factory

    /subsystem=elytron/configurable-sasl-server-factory=configured:list-add(name=filters, value={pattern-filter=GSSAPI})

    This is an optional step. When a client attempts to connect to the HTTP management interfaces, JBoss EAP sends back an HTTP response with a status code of 401 Unauthorized, and a set of headers that list the supported authentication mechanisms, for example, Digest, GSSAPI, and so on. For more information, see the Local and Remote Client Authentication with the HTTP Interface section in the JBoss EAP Security Architecture guide.

  4. Update the management interfaces to use your http-authentication-factory or sasl-authentication-factory.

    Example: Update http-authentication-factory

    /core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=example-http-auth)
    
    reload

    Example: Update sasl-authentication-factory

    /core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade.sasl-authentication-factory, value=example-sasl-auth)
    
    reload

    You can also update the native interface to use a sasl-authentication-factory.

    Note

    The native interface is not enabled by default.

    Example: Add Native Interface and Use sasl-authentication-factory

    /socket-binding-group=standard-sockets/socket-binding=native:add(interface=management, port=9999)
    
    /core-service=management/management-interface=native-interface:add(socket-binding=native)
    
    /core-service=management/management-interface=native-interface:write-attribute(name=sasl-authentication-factory, value=example-sasl-auth)
    
    reload

Note

When using legacy core management authentication, you can only secure the http management interface with a single legacy security realm. This forces the HTTP and SASL configuration to appear in a single legacy security realm. When using the elytron subsystem, you can configure the http-authentication-factory and sasl-authentication-factory separately, allowing you to use distinct security domains for securing the HTTP and SASL mechanisms of the http management interface.

Note

If two different attributes with similar implementation in legacy security and Elytron, respectively, are configured in the management interface, only the Elytron related configurations are used. For example, if security-realm for legacy security and http-authentication-factory for Elytron are configured, then authentication is handled by http-authentication-factory configuration.

Note

When the management interface includes both http-authentication-factory, or sasl-authentication-factory for the native interface, as well as the security-realm, and the ssl-context attribute is not used, the authentication is handled by Elytron and the SSL is handled by the legacy security realm.

When the management interface includes both the security-realm and the ssl-context, and the http-authentication-factory or sasl-authentication-factory for the native interface is not used, then authentication is handled by the legacy security realm and SSL is handled by Elytron.

3.1.3. Adding Silent Authentication

By default, JBoss EAP provides an authentication mechanism for local users, also know as silent authentication, through the local security realm. You can find more details on silent authentication in the Silent Authentication section.

Silent authentication must be added to a sasl-authentication-factory.

To add silent authentication to an existing sasl-authentication-factory:

/subsystem=elytron/sasl-authentication-factory=example-sasl-auth:list-add(name=mechanism-configurations, value={mechanism-name=JBOSS-LOCAL-USER, realm-mapper=local})

reload

To create a new sasl-server-factory with silent authentication:

/subsystem=elytron/sasl-authentication-factory=example-sasl-auth:add(sasl-server-factory=configured,security-domain=ManagementDomain,mechanism-configurations=[{mechanism-name=DIGEST-MD5,mechanism-realm-configurations=[{realm-name=exampleManagementRealm}]},{mechanism-name=JBOSS-LOCAL-USER, realm-mapper=local}])

reload
Note

The above example uses the existing ManagementDomain security domain, but you can also create and use other security domains. You can find more examples of creating security domains in the Elytron Subsystem section of the JBoss EAP How to Configure Identity Management Guide.

Important

If the Elytron security is used and an authentication attempt comes in using the JBOSS-LOCAL-USER SASL mechanism with an authentication name that does not correspond to a real identity, authentication fails.

Choosing a custom user name for JBOSS-LOCAL-USER is possible with legacy security subsystem. There the authentication proceeds by mapping the user name to a special identity.

3.1.4. Mapping Identity for Authenticated Management Users

When using the elytron subsystem to secure the management interfaces, you can provide a security domain to the management interfaces for identity mapping of authenticated users. This allows authenticated users to appear with the appropriate identity when logged into the management interfaces.

The application server exposes more than one kind of management interface. Each type of interface can be associated with an independent authentication-factory to handle the authentication requirements of that interface.

To make the authorization decision, the current security identity is obtained from the security domain. The returned security identity has the role mapping and permission assignment, based on the rules defined within that security domain.

Note

In most cases, a common security domain is used for all management; for authentication of the management interfaces as well as for obtaining the security identity used for the authorization decisions. In these cases, the security domain is associated with the authentication factory of the management interface and no special access=identity needs to be defined.

In some cases, a different security domain is used to obtain the identity for the authorization decisions. Here, the access=identity resource is defined. It contains a reference to a security domain to obtain the identity for authorization.

The below example assumes you have secured the management interfaces with the exampleSD Elytron security domain and have it exposed as exampleManagementRealm.

To define the identity mapping, add the identity resource to the management interfaces.

Example: Add the identity Resource

/core-service=management/access=identity:add(security-domain=exampleSD)

Once you have added the identity resource, the identity of an authenticated user will appear when accessing the management interfaces. When the identity resource is not added, then the identity of the security domain used for authentication is used.

For example, if you logged into the management CLI as user1, your identity will properly appear.

Example: Display the Identity of an Authenticated User from the Management CLI

:whoami
{
    "outcome" => "success",
    "result" => {"identity" => {"username" => "user1"}}
}

Important

If the identity resource is added and legacy security realms are used to secure the management interfaces, authenticated users will always have the anonymous identity. Once the identity resource is removed, users authenticated from the legacy security realms will appear with the appropriate identity.

Authorization for management operation always uses the security domain, which is the domain specified on access=identity. If not specified, it is the domain used for authentication. Any role mapping is always in the context of the security domain.

The identity resource for the current request will return a set of roles as mapped using the Elytron configuration. When an RBAC based role mapping definition is in use, the roles from the identity resource will be taken as groups and fed into the management RoleMapping to obtain the management roles for the current request.

Table 3.1. Identity to be Used for Different Scenarios

ScenarioNo access=identity definitionaccess=identity referencing an Elytron security-domain

HTTP management interface using legacy security-realm

Identity from connection.

Unsupported or anonymous identity.

HTTP management interface using elytron HTTP authentication factory backed by security-domain

Identity from connection.

Identity from referenced security-domain if it was successfully inflowed.

Native management, including over HTTP Upgrade, interface using legacy security-realm

Identity from connection.

Unsupported or anonymous identity.

Native management, including over HTTP Upgrade, interface using elytron SASL authentication factory backed by security-domain

Identity from connection.

Identity from referenced security-domain if it was successfully inflowed.

Note

If security domain used in the identity resource does not trust the security domain from authentication, anonymous identity is used.

The security domain used in the identity resource does not need to trust the security domain from authentication, when both are using an identical security realm.

The trusted security domains is not transitive.

Where no access=identity resource is defined, then the identity established during authentication against the management interface will be used. Identities established using connections, through the remoting subsystem or using applications, will not be usable in this case.

Where an access=identity resource is defined but the security domain used by the management interfaces is different and not listed in the list of domains to inflow from, no identity will be established. An inflow will be attempted using the identity established during authentication. Identities established using connections through the remoting subsystem or using applications will not be inflowed in this way.

Important

Where the management interfaces are secured using the legacy security realms, the identity will not be sharable across different security domains. In that case no access=identity resource should be defined. So the identity established during authentication can be used directly. Thus, applications secured using PicketBox are not supported for the identity resource.

3.1.5. Using Elytron Client with the Management CLI

You can configure the management CLI to use Elytron Client for providing security information when connecting to JBoss EAP.

  1. Secure the management interfaces with Elytron.

    In order to use Elytron Client with the management CLI, you must secure the management interfaces with Elytron. You can find more details on securing the management interfaces with Elytron in User Authentication with Elytron.

  2. Create an Elytron Client configuration file.

    You need to create an Elytron Client configuration file that houses your authentication configuration as well as rules for using that configuration. You can find more details on creating an authentication configuration in the The Configuration File Approach section of the JBoss EAP How to Configure Identity Management Guide.

    Example: custom-config.xml

    <configuration>
        <authentication-client xmlns="urn:elytron:1.0.1">
            <authentication-rules>
                <rule use-configuration="configuration1">
                    <match-host name="localhost" />
                </rule>
            </authentication-rules>
            <authentication-configurations>
                <configuration name="configuration1">
                    <sasl-mechanism-selector selector="DIGEST-MD5" />
                    <providers>
                      <use-service-loader />
                    </providers>
                    <set-user-name name="user1" />
                    <credentials>
                        <clear-password password="password123" />
                    </credentials>
                    <set-mechanism-realm name="exampleManagementRealm" />
                 </configuration>
            </authentication-configurations>
        </authentication-client>
    </configuration>

  3. Use the Elytron Client configuration file with management CLI script.

    $ ./jboss-cli.sh -c  -Dwildfly.config.url=/path/to/custom-config.xml

3.2. Identity Propagation and Forwarding with Elytron

3.2.1. Propagating Security Identities for Remote Calls

JBoss EAP 7.1 introduces the ability to easily configure the server and your applications to propagate a security identity from a client to the server for remoting calls. You can also configure server components to run within the security identity of a given user.

The example in this section demonstrates how to forward security identity credentials. It propagates the security identity of a client and an EJB to a remote EJB. It returns a string containing the name of the Principal that called the remote EJB along with the user’s authorized role information. The example consists of the following components.

  • A secured EJB that contains a single method, accessible by all users, that returns authorization information about the caller.
  • An intermediate EJB that contains a single method. It makes use of a remote connection and invokes the method on the secured EJB.
  • A remote standalone client application that invokes the intermediate EJB.
  • A META-INF/wildfly-config.xml file that contains the identity information used for authentication.

You must first enable security identity propagation by configuring the server. Next review the example application code that uses the WildFlyInitialContextFactory to look up and invoke the remote EJB.

Configure the Server for Security Propagation
  1. Configure the ejb3 subsystem to use the Elytron ApplicationDomain.

    /subsystem=ejb3/application-security-domain=quickstart-domain:add(security-domain=ApplicationDomain)

    This adds the following application-security-domain configuration to the ejb3 subsystem.

    <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
        ....
        <application-security-domains>
            <application-security-domain name="quickstart-domain" security-domain="ApplicationDomain"/>
        </application-security-domains>
    </subsystem>
  2. Add the PLAIN authentication configuration to send plain text user names and passwords, and the authentication context that is to be used for outbound connections. See Mechanisms That Support Security Identity Propagation for the list of mechanisms that support identity propagation.

    /subsystem=elytron/authentication-configuration=ejb-outbound-configuration:add(security-domain=ApplicationDomain,sasl-mechanism-selector="PLAIN")
    /subsystem=elytron/authentication-context=ejb-outbound-context:add(match-rules=[{authentication-configuration=ejb-outbound-configuration}])

    This adds the following authentication-client configuration to the elytron subsystem.

    <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
        <authentication-client>
            <authentication-configuration name="ejb-outbound-configuration" security-domain="ApplicationDomain" sasl-mechanism-selector="PLAIN"/>
            <authentication-context name="ejb-outbound-context">
                <match-rule authentication-configuration="ejb-outbound-configuration"/>
            </authentication-context>
        </authentication-client>
        ....
    </subsystem>
  3. Add the remote destination outbound socket binding to the standard-sockets socket binding group.

    /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=ejb-outbound:add(host=localhost,port=8080)

    This adds the following ejb-outbound outbound socket binding to the standard-sockets socket binding group.

    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
        ....
        <outbound-socket-binding name="ejb-outbound">
            <remote-destination host="localhost" port="8080"/>
        </outbound-socket-binding>
    </socket-binding-group>
  4. Add the remote outbound connection and set the SASL authentication factory in the HTTP connector.

    /subsystem=remoting/remote-outbound-connection=ejb-outbound-connection:add(outbound-socket-binding-ref=ejb-outbound, authentication-context=ejb-outbound-context)
    /subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=sasl-authentication-factory,value=application-sasl-authentication)

    This adds the following http-remoting-connector and ejb-outbound-connection configuration to the remoting subsystem.

    <subsystem xmlns="urn:jboss:domain:remoting:4.0">
        ....
        <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm" sasl-authentication-factory="application-sasl-authentication"/>
        <outbound-connections>
            <remote-outbound-connection name="ejb-outbound-connection" outbound-socket-binding-ref="ejb-outbound" authentication-context="ejb-outbound-context"/>
        </outbound-connections>
    </subsystem>
  5. Configure the Elytron SASL authentication to use the PLAIN mechanism.

    /subsystem=elytron/sasl-authentication-factory=application-sasl-authentication:write-attribute(name=mechanism-configurations,value=[{mechanism-name=PLAIN},{mechanism-name=JBOSS-LOCAL-USER,realm-mapper=local},{mechanism-name=DIGEST-MD5,mechanism-realm-configurations=[{realm-name=ApplicationRealm}]}])

    This adds the following application-sasl-authentication configuration to the elytron subsystem.

    <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
        ....
        <sasl>
          ....
          <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
              <mechanism-configuration>
                  <mechanism mechanism-name="PLAIN"/>
                  <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
                  <mechanism mechanism-name="DIGEST-MD5">
                      <mechanism-realm realm-name="ApplicationRealm"/>
                  </mechanism>
              </mechanism-configuration>
          </sasl-authentication-factory>
      </sasl>
      ....
    </subsystem>

The server is now configured to enable security propagation for the following example application.

Review the Example Application Code That Propagates a Security Identity

Once security identity propagation is enabled in the server configuration, the EJB client application can use the WildFlyInitialContextFactory to look up and invoke the EJB proxy. The EJB is invoked as the user that authenticated in the client example shown below. The following abbreviated code examples are taken from the ejb-security-context-propagation quickstart that ships with JBoss EAP 7.1. See that quickstart for a complete working example of security identity propagation.

To invoke the EJB as a different user, you can set the Context.SECURITY_PRINCIPAL and Context.SECURITY_CREDENTIALS in the context properties.

Example: Remote Client

public class RemoteClient {

    public static void main(String[] args) throws Exception {
        // invoke the intermediate bean using the identity configured in wildfly-config.xml
        invokeIntermediateBean();

        // now lets programmatically setup an authentication context to switch users before invoking the intermediate bean
        AuthenticationConfiguration superUser = AuthenticationConfiguration.empty().setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("PLAIN")).
                useName("superUser").usePassword("superPwd1!");
        final AuthenticationContext authCtx = AuthenticationContext.empty().
                with(MatchRule.ALL, superUser);

        AuthenticationContext.getContextManager().setThreadDefault(authCtx);
        invokeIntermediateBean();
    }

    private static void invokeIntermediateBean() throws Exception {
        final Hashtable<String, String> jndiProperties = new Hashtable<>();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
        jndiProperties.put(Context.PROVIDER_URL, "remote+http://localhost:8080");
        final Context context = new InitialContext(jndiProperties);
        IntermediateEJBRemote intermediate = (IntermediateEJBRemote) context.lookup("ejb:/ejb-security-context-propagation/IntermediateEJB!"
                + IntermediateEJBRemote.class.getName());
        // Call the intermediate EJB
        System.out.println(intermediate.makeRemoteCalls());
    }
}

Example: Intermediate EJB

@Stateless
@Remote(IntermediateEJBRemote.class)
@SecurityDomain("quickstart-domain")
@PermitAll
public class IntermediateEJB implements IntermediateEJBRemote {

    @EJB(lookup="ejb:/ejb-security-context-propagation/SecuredEJB!org.jboss.as.quickstarts.ejb_security_context_propagation.SecuredEJBRemote")
    private SecuredEJBRemote remote;

    @Resource
    private EJBContext context;

    public String makeRemoteCalls() {
        try {
            StringBuilder sb = new StringBuilder("** ").
                    append(context.getCallerPrincipal()).
                    append(" * * \n\n");
            sb.append("Remote Security Information: ").
                    append(remote.getSecurityInformation()).
                    append("\n");

            return sb.toString();
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
            throw new RuntimeException("Teasting failed.", e);
        }
    }
}

Example: Secured EJB

@Stateless
@Remote(SecuredEJBRemote.class)
@SecurityDomain("quickstart-domain")
public class SecuredEJB implements SecuredEJBRemote {

    @Resource
    private SessionContext context;

    @PermitAll
    public String getSecurityInformation() {
        StringBuilder sb = new StringBuilder("[");
        sb.append("Principal=[").
                append(context.getCallerPrincipal().getName()).
                append("], ");
        userInRole("guest", sb).append(", ");
        userInRole("user", sb).append(", ");
        userInRole("admin", sb).append("]");
        return sb.toString();
    }
}

Example: wildfly-config.xml File

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <authentication-client xmlns="urn:elytron:1.0.1">
        <authentication-rules>
            <rule use-configuration="default"/>
        </authentication-rules>
        <authentication-configurations>
            <configuration name="default">
                <set-user-name name="quickstartUser"/>
                <credentials>
                    <clear-password password="quickstartPwd1!"/>
                </credentials>
                <sasl-mechanism-selector selector="PLAIN"/>
                <providers>
                    <use-service-loader />
                </providers>
            </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>

3.2.2. Utilizing Authorization Forwarding Mode

In addition to credential forwarding, Elytron supports the trusted use of identities between peers. This can be useful in the following cases.

  • Requirements are such that you cannot send passwords over the wire.
  • The authentication type is one that does not support credential forwarding.
  • The environment requires a need to limit which systems are allowed to receive the propagated requests.

To utilize authorization forwarding, you first configure an authentication client on the forwarding server and then configure the receiving server to accept and handle the authorization.

Configure the Authentication Client on the Forwarding Server

To enable authorization forwarding, you must configure an authentication client configuration in the forwarding server configuration.

The following management CLI commands create a default authentication client configuration to enable authentication forwarding. You can configure a more advanced rule based selection if you need one.

Example: Management CLI Command to Create the Authentication Client Configuration

/subsystem=elytron/authentication-configuration=forwardit:add(authentication-name=theserver1,security-domain=ApplicationDomain,realm=ApplicationRealm,forwarding-mode=authorization,credential-reference={clear-text=thereallysecretpassword})
/subsystem=elytron/authentication-context=forwardctx:add(match-rules=[{authentication-configuration=forwardit,match-no-user=true}])

These commands add the following authentication-configuration and authentication-context configuration to the elytron subsystem.

Example: Authentication Client Configuration

<authentication-client>
    <authentication-configuration name="forwardit" authentication-name="theserver1" security-domain="ApplicationDomain" forwarding-mode="authorization" realm="ApplicationRealm">
        <credential-reference clear-text="thereallysecretpassword"/>
    </authentication-configuration>
    <authentication-context name="forwardctx">
        <match-rule match-no-user="true" authentication-configuration="forwardit"/>
    </authentication-context>
</authentication-client>

When the forwarding server contacts the receiving server, instead of using the default authentication-based user name and credentials, it uses the predefined server login name theserver1 to establish the trust relationship.

Configure the Authorization Forwarding on the Receiving Server

For the forwarding to complete successfully, the receiving server configuration needs to be configured with the identity matching the one passed by the forwarding server. In this case, you must configure a user named theserver1 on the receiving server with the correct credentials.

You must also configure a "RunAs" permission mapping in the elytron subsystem to allow the identity switch for the theserver1 identity that is passed from the forwarding server. For more information about permission mapping, see Create an Elytron Permission Mapper in How to Configure Server Security for JBoss EAP.

The command below adds a simple-permission-mapper named auth-forwarding-permission-mapper that includes the following configurations.

  • A permission mapping for the user anonymous. This user has no permissions, which prevents an anonymous user from being able to log in.
  • A permission mapping for the user theserver1. This user is assigned the RunAsPrincipalPermission permission of *, which gives this user global permissions to run as any identity. You can restrict the permission to a specific identity if you prefer.
  • A permission mapping for all other users.

Example: Management CLI Command to the Create Simple Permission Mapper

/subsystem=elytron/simple-permission-mapper=auth-forwarding-permission-mapper:add(permission-mappings=[{principals=["anonymous"]},{principals=["theserver1"],permissions=[{class-name="org.wildfly.security.auth.permission.RunAsPrincipalPermission",target-name="*"},{class-name="org.wildfly.security.auth.permission.LoginPermission"},{class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission",module="org.wildfly.extension.batch.jberet",target-name="*"},{class-name="org.wildfly.transaction.client.RemoteTransactionPermission",module="org.wildfly.transaction.client"},{class-name="org.jboss.ejb.client.RemoteEJBPermission",module="org.jboss.ejb-client"}]},{match-all=true,permissions=[{class-name="org.wildfly.security.auth.permission.LoginPermission"},{class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission",module="org.wildfly.extension.batch.jberet",target-name="*"},{class-name="org.wildfly.transaction.client.RemoteTransactionPermission",module="org.wildfly.transaction.client"},{class-name="org.jboss.ejb.client.RemoteEJBPermission",module="org.jboss.ejb-client"}]}])

This command adds the following simple-permission-mapper configuration to the elytron subsystem.

Example: Simple Permission Mapper Configuration

<simple-permission-mapper name="auth-forwarding-permission-mapper">
    <permission-mapping>
        <principal name="anonymous"/>
        <!-- No permissions: Deny any permission to anonymous! -->
    </permission-mapping>
    <permission-mapping>
        <principal name="theserver1"/>
        <permission class-name="org.wildfly.security.auth.permission.RunAsPrincipalPermission" target-name="*"/>
        <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
        <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
        <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
        <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
    </permission-mapping>
    <permission-mapping match-all="true">
        <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
        <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
        <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
        <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
    </permission-mapping>
</simple-permission-mapper>

In cases where principal transformers are used after forwarding authorization, then those transformers are applied on both the authentication and the authorization principals.

3.2.3. Retrieving Security Identity Credentials

There might be situations where you need to retrieve identity credentials for use in outgoing calls, for example, by an HTTP client. The following example demonstrates how to retrieve security credentials programmatically.

import org.wildfly.security.auth.server.IdentityCredentials;
import org.wildfly.security.auth.server.SecurityDomain;
import org.wildfly.security.auth.server.SecurityIdentity;
import org.wildfly.security.credential.PasswordCredential;
import org.wildfly.security.password.interfaces.ClearPassword;

SecurityIdentity securityIdentity = null;
ClearPassword password = null;

// Obtain the SecurityDomain for the current deployment.
// The calling code requires the
//     org.wildfly.security.permission.ElytronPermission("getSecurityDomain") permission
//     if running with a security manager.
SecurityDomain securityDomain = SecurityDomain.getCurrent();
if (securityDomain != null) {
    // Obtain the current security identity from the security domain.
    // This always returns an identity, but it could be the representation
    //     of the anonymous identity if no authenticated identity is available.
    securityIdentity = securityDomain.getCurrentSecurityIdentity();
    // The private credentials can be accessed to obtain any credentials delegated to the identity.
    // The calling code requires the
    //     org.wildfly.security.permission.ElytronPermission("getPrivateCredentials")
    //     permission if running with a security manager.
    IdentityCredentials credentials = securityIdentity.getPrivateCredentials();
    if (credentials.contains(PasswordCredential.class)) {
        password = credentials.getCredential(PasswordCredential.class).getPassword(ClearPassword.class);
    }
}

3.2.4. Mechanisms That Support Security Identity Propagation

The following SASL mechanisms support propagation of security identities:

  • PLAIN
  • OAUTHBEARER
  • GSSAPI
  • GS2-KRB5

The following HTTP mechanisms support propagation of security identities:

  • FORM 1
  • BASIC
  • BEARER_TOKEN
  • SPNEGO

1 FORM authentication is not automatically handled by the web browser. For this reason, you cannot use identity propagation with web applications that use FORM authentication when running in an HA cluster. Other mechanisms, such as BASIC and SPNEGO, support identity propagation in an HA cluster environment.

3.3. Identity Switching with Elytron

3.3.1. Switching Identities in Server-to-server EJB Calls

By default, when you make a remote call to an EJB deployed to an application server, the identity used for authentication on the remote server is the same one that was used on the source server. In some cases, you might want to run the remote secured EJB within the security context of a different identity.

You can use the Elytron API to switch identities in server-to-server EJB calls. When you do that, the request received over the connection is executed as a new request, using the identity specified programmatically in the API call.

The following code example demonstrates how to switch the identity that is used for authentication on a remote EJB. The remoteUsername and remotePassword arguments passed in the securityDomain.authenticate() method are the identity credentials that are to be used for authentication on the target server.

Example: Switching Identities in Server-to-server EJB Calls

SecurityDomain securityDomain = SecurityDomain.getCurrent();
Callable<T> forwardIdentityCallable = () -> {
    return AuthenticationContext.empty()
            .with(MatchRule.ALL,
                    AuthenticationConfiguration.empty()
                    .setSaslMechanismSelector(SaslMechanismSelector.ALL)
                    .useForwardedIdentity(securityDomain))
            .runCallable(callable);
};

securityDomain.authenticate(remoteUsername, new PasswordGuessEvidence(remotePassword.toCharArray())).runAs(forwardIdentityCallable);

3.4. User Authentication with Legacy Core Management Authentication

3.4.1. Default User Configuration

All management interfaces in JBoss EAP are secured by default and users can access them in two different ways: local interfaces and remote interfaces. The basics of both of these authentication mechanisms are covered in the Default Security and JBoss EAP Out of the Box sections of the JBoss EAP Security Architecture guide. By default, access to these interfaces is configured in the Management Realm security realm. Initially, the local interface is enabled and requires access to the host machine running the JBoss EAP instance. Remote access is also enabled and is configured to use a file-based identity store. By default it uses mgmt-users.properties file to store user names and passwords, and mgmt-groups.properties to store user group information.

User information is added to these files by using the included adduser script located in the EAP_HOME/bin/ directory.

To add a user via the adduser script:

  1. Run the add-user.sh or add-user.bat command.
  2. Choose whether to add a management user or application user.
  3. Choose the realm the user will be added to. By default, the only available realms are ManagementRealm and ApplicationRealm. If a custom realm has been added, its name can be manually entered instead.
  4. Type the desired user name, password, and optional roles when prompted. The changes are written to each of the properties files for the security realm.

3.4.2. Adding Authentication via LDAP

JBoss EAP also supports using LDAP authentication for securing the management interfaces. The basics of LDAP and how it works with JBoss EAP are covered in the LDAP, Using LDAP with the Management Interfaces, and Using LDAP with the ManagementRealm sections of the Red Hat JBoss Enterprise Application Platform 7 Security Architecture guide. For more specifics on how to secure the management interfaces using LDAP authentication, see the Securing the Management Interfaces with LDAP section of the JBoss EAP How to Configure Identity Management Guide.

3.4.3. Using JAAS for Securing the Management Interfaces

JAAS is a declarative security API used by JBoss EAP to manage security. For more details and background regarding JAAS and declarative security, see the Declarative Security and JAAS section of the Red Hat JBoss Enterprise Application Platform Security Architecture guide.

Note

When JBoss EAP instances are configured to run in ADMIN_ONLY mode, using JAAS to secure the management interfaces is not supported. For more information on ADMIN_ONLY mode, see the Running JBoss EAP in ADMIN_ONLY Mode section of the JBoss EAP Configuration Guide.

To use JAAS to authenticate to the management interfaces, the following steps must be performed:

  1. Create a security domain.

    In this example, a security domain is created with the UserRoles login module, but other login modules may be used as well:

    /subsystem=security/security-domain=UsersLMDomain:add(cache-type=default)
    
    /subsystem=security/security-domain=UsersLMDomain/authentication=classic:add
    
    /subsystem=security/security-domain=UsersLMDomain/authentication=classic/login-module=UsersRoles:add(code=UsersRoles, flag=required,module-options=[("usersProperties"=>"users.properties"),("rolesProperties"=>"roles.properties")])
  2. Create a security realm with JAAS authentication.

    /core-service=management/security-realm=SecurityDomainAuthnRealm:add
    
    /core-service=management/security-realm=SecurityDomainAuthnRealm/authentication=jaas:add(name=UsersLMDomain)
  3. Update the http-interface management interface to use new security realm.

    /core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=SecurityDomainAuthnRealm)
  4. Optional: Assign group membership.

    The attribute assign-groups determines whether loaded user membership information from the security domain is used for group assignment in the security realm. When set to true, this group assignment is used for Role-Based Access Control (RBAC).

    /core-service=management/security-realm=SecurityDomainAuthnRealm/authentication=jaas:write-attribute(name=assign-groups,value=true)

3.5. Role-Based Access Control

The basics of Role-Based Access Control are covered in the Role-Based Access Control and Adding RBAC to the Management Interfaces sections of the JBoss EAP Security Architecture guide.

3.5.1. Enabling Role-Based Access Control

By default the Role-Based Access Control (RBAC) system is disabled. It is enabled by changing the provider attribute from simple to rbac. provider is an attribute of the access-control element of the management element. This can be done using the management CLI or by editing the server configuration XML file if the server is offline. When RBAC is disabled or enabled on a running server, the server configuration must be reloaded before it takes effect.

Warning

Before changing the provider to rbac, be sure your configuration has a user who will be mapped to one of the RBAC roles, preferably with at least one in the Administrator or SuperUser role. Otherwise your installation will not be manageable except by shutting it down and editing the XML configuration. If you have started with one of the standard XML configurations shipped with JBoss EAP, the $local user will be mapped to the SuperUser role and the local authentication scheme will be enabled. This will allow a user, running the CLI on the same system as the JBoss EAP process, to have full administrative permissions. Remote CLI users and web-based management console users will have no permissions.

It is recommended to map at least one user, besides $local, before switching the provider to rbac. You can do all of the configuration associated with the rbac provider even when the provider is set to simple.

Once enabled it can only be disabled by a user of the Administrator or SuperUser roles. By default the management CLI runs as the SuperUser role if it is run on the same machine as the server.

CLI to Enable RBAC

To enable RBAC with the management CLI, use the write-attribute operation of the access authorization resource to set the provider attribute to rbac.

/core-service=management/access=authorization:write-attribute(name=provider, value=rbac)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

reload

In a managed domain, the access control configuration is part of the domain wide configuration, so the resource address is the same as above, but the management CLI is connected to the master domain controller.

/core-service=management/access=authorization:write-attribute(name=provider,value=rbac)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    },
    "result" => undefined,
    "server-groups" => {"main-server-group" => {"host" => {"master" => {
        "server-one" => {"response" => {
            "outcome" => "success",
            "response-headers" => {
                "operation-requires-reload" => true,
                "process-state" => "reload-required"
            }
        }},
        "server-two" => {"response" => {
            "outcome" => "success",
            "response-headers" => {
                "operation-requires-reload" => true,
                "process-state" => "reload-required"
            }
        }}
    }}}}
}

reload --host=master
Note

As with a standalone server, a reload or restart is required for the change to take effect. In a managed domain, all hosts and servers in the domain will need to be reloaded or restarted, starting with the master domain controller.

Management CLI Command to Disable RBAC

To disable RBAC with the management CLI, use the write-attribute operation of the access authorization resource to set the provider attribute to simple.

/core-service=management/access=authorization:write-attribute(name=provider, value=simple)
XML Configuration to Enable or Disable RBAC

If the server is offline the XML configuration can be edited to enable or disable RBAC. To do this, edit the provider attribute of the access-control element of the management element. Set the value to rbac to enable, and simple to disable.

Example: XML Configuration to Enable or Disable RBAC

<management>
  <access-control provider="rbac">
    <role-mapping>
      <role name="SuperUser">
        <include>
          <user name="$local"/>
        </include>
      </role>
    </role-mapping>
  </access-control>
</management>

3.5.2. Changing the Permission Combination Policy

The Permission Combination Policy determines how permissions are determined if a user is assigned more than one role. This can be set to permissive or rejecting. The default is permissive.

When set to permissive, if any role is assigned to the user that permits an action, then the action is allowed.

When set to rejecting, if multiple roles are assigned to a user, then no action is allowed. This means that when the policy is set to rejecting each user should only be assigned one role. Users with multiple roles will not be able to use the management console or the management CLI when the policy is set to rejecting.

The Permission Combination Policy is configured by setting the permission-combination-policy attribute to either permissive or rejecting. This can be done using the management CLI or by editing the server configuration XML file if the server is offline. The permission-combination-policy attribute is part of the access-control element and the access-control element can be found in the management element.

Setting the Permission Combination Policy

Use the write-attribute operation of the access authorization resource to set the permission-combination-policy attribute to the required policy name.

/core-service=management/access=authorization:write-attribute(name=permission-combination-policy, value=POLICYNAME)

The valid policy names are rejecting and permissive.

Example: Management CLI Command for Rejecting Permission Combination Policy

/core-service=management/access=authorization:write-attribute(name=permission-combination-policy, value=rejecting)

If the server is offline the XML configuration can be edited to change the permission combination policy value. To do this, edit the permission-combination-policy attribute of the access-control element.

Example: XML Configuration for Rejecting Permission Combination Policy

<access-control provider="rbac" permission-combination-policy="rejecting">
  <role-mapping>
    <role name="SuperUser">
      <include>
        <user name="$local"/>
      </include>
    </role>
  </role-mapping>
</access-control>

3.5.3. Managing Roles

When Role-Based Access Control (RBAC) is enabled, what a management user is permitted to do is determined by the roles to which the user is assigned. JBoss EAP 7 uses a system of includes and excludes based on both the user and group membership to determine to which role a user belongs.

A user is considered to be assigned to a role if the user is:

  • listed as a user to be included in the role, or
  • a member of a group that is listed to be included in the role.

A user is also considered to be assigned to a role if the user is not:

  • listed as a user to exclude from the role, or
  • a member of a group that is listed to be excluded from the role.

Exclusions take priority over inclusions.

Role include and exclude settings for users and groups can be configured using both the management console and the management CLI.

Only users of the SuperUser or Administrator roles can perform this configuration.

3.5.3.1. Configure User Role Assignment Using the Management CLI

The configuration of mapping users and groups to roles is located at: /core-service=management/access=authorization as role-mapping elements.

Only users of the SuperUser or Administrator roles can perform this configuration.

Viewing Role Assignment Configuration

Use the :read-children-names operation to get a complete list of the configured roles:

/core-service=management/access=authorization:read-children-names(child-type=role-mapping)
{
    "outcome" => "success",
    "result" => [
        "Administrator",
        "Deployer",
        "Maintainer",
        "Monitor",
        "Operator",
        "SuperUser"
    ]
}

Use the read-resource operation of a specified role-mapping to get the full details of a specific role:

/core-service=management/access=authorization/role-mapping=ROLENAME:read-resource(recursive=true)
{
    "outcome" => "success",
    "result" => {
        "include-all" => false,
        "exclude" => undefined,
        "include" => {
            "user-theboss" => {
                "name" => "theboss",
                "realm" => undefined,
                "type" => "USER"
            },
            "user-harold" => {
                "name" => "harold",
                "realm" => undefined,
                "type" => "USER"
            },
            "group-SysOps" => {
                "name" => "SysOps",
                "realm" => undefined,
                "type" => "GROUP"
            }
        }
    }
}
Add a New Role

This procedure shows how to add a role-mapping entry for a role. This must be done before the role can be configured.

Use the add operation to add a new role configuration.

/core-service=management/access=authorization/role-mapping=ROLENAME:add

ROLENAME is the name of the role that the new mapping is for, such as Auditor.

Example: Management CLI Command for New Role Configuration

/core-service=management/access=authorization/role-mapping=Auditor:add

Add a User as Included in a Role

This procedure shows how to add a user to the included list of a role.

If no configuration for a role has been done, then a role-mapping entry for it must be done first.

Use the add operation to add a user entry to the includes list of the role.

/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:add(name=USERNAME, type=USER)
  • ROLENAME is the name of the role being configured, such as Auditor.
  • ALIAS is a unique name for this mapping. Red Hat recommends the use of a naming convention for aliases, such as user-USERNAME (for example, user-max).
  • USERNAME is the name of the user being added to the include list, such as max.

Example: Management CLI Command for User Included in a Role

/core-service=management/access=authorization/role-mapping=Auditor/include=user-max:add(name=max, type=USER)

Add a User as Excluded in a Role

This procedure shows how to add a user to the excluded list of a role.

If no configuration for a role has been done, then a role-mapping entry for it must be done first.

Use the add operation to add a user entry to the excludes list of the role.

/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:add(name=USERNAME, type=USER)
  • ROLENAME is the name of the role being configured, for example Auditor.
  • USERNAME is the name of the user being added to the exclude list, for example max.
  • ALIAS is a unique name for this mapping. Red Hat recommends that the use of a naming convention for aliases, such as user-USERNAME (for example, user-max).

Example: Management CLI Command User Excluded in a Role

/core-service=management/access=authorization/role-mapping=Auditor/exclude=user-max:add(name=max, type=USER)

Remove User Role Include Configuration

This procedure shows how to remove a user include entry from a role mapping.

Use the remove operation to remove the entry.

/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:remove
  • ROLENAME is the name of the role being configured, such as Auditor.
  • ALIAS is a unique name for this mapping. Red Hat recommends that the use of a naming convention for aliases, such as user-USERNAME (for example, user-max).

Example: Management CLI Command for Removing User Role Include Configuration

/core-service=management/access=authorization/role-mapping=Auditor/include=user-max:remove

Note

Removing the user from the list of includes does not remove the user from the system, nor does it guarantee that the role will not be assigned to the user. The role might still be assigned based on group membership.

Remove User Role Exclude Configuration

This procedure shows how to remove an user exclude entry from a role mapping.

Use the remove operation to remove the entry.

/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:remove
  • ROLENAME is the name of the role being configured, such as Auditor.
  • ALIAS is a unique name for this mapping. Red Hat recommends that the use of a naming convention for aliases, such as user-USERNAME (for example, user-max).
/core-service=management/access=authorization/role-mapping=Auditor/exclude=user-max:remove
Note

Removing the user from the list of excludes does not remove the user from the system, nor does it guarantee the role will be assigned to the user. Roles might still be excluded based on group membership.

3.5.4. Configure User Role Assignment with the Elytron Subsystem

In addition to adding role mappings for users directly, as covered in Managing Roles section, you can also configure RBAC roles to be directly taken from the identity provided by the elytron subsystem.

To configure the RBAC system to use roles provided by the elytron subsystem:

/core-service=management/access=authorization:write-attribute(name=use-identity-roles,value=true)
Important

RBAC must be enabled to use this functionality, and the principal must have RBAC roles.

3.5.5. Roles and User Groups

A user group is an arbitrary label that can be assigned to one or more users. When authenticating using the management interfaces, users are assigned groups from either the elytron subsystem or core management authentication, depending on how the management interfaces are secured. The RBAC system can be configured to automatically assign roles to users depending on what user groups they are members of. It can also exclude users from roles based on group membership.

3.5.6. Configure Group Role Assignment Using the Management CLI

Groups to be included or excluded from a role can be configured in the management console and the management CLI. This topic only shows using the management CLI.

The configuration of mapping users and groups to roles is located in the management API at: /core-service=management/access=authorization as role-mapping elements.

Only users in the SuperUser or Administrator roles can perform this configuration.

Viewing Group Role Assignment Configuration

Use the read-children-names operation to get a complete list of the configured roles:

/core-service=management/access=authorization:read-children-names(child-type=role-mapping)
{
    "outcome" => "success",
    "result" => [
        "Administrator",
        "Deployer",
        "Maintainer",
        "Monitor",
        "Operator",
        "SuperUser"
    ]
}

Use the read-resource operation of a specified role-mapping to get the full details of a specific role:

/core-service=management/access=authorization/role-mapping=ROLENAME:read-resource(recursive=true)
{
    "outcome" => "success",
    "result" => {
        "include-all" => false,
        "exclude" => undefined,
        "include" => {
            "user-theboss" => {
                "name" => "theboss",
                "realm" => undefined,
                "type" => "USER"
            },
            "user-harold" => {
                "name" => "harold",
                "realm" => undefined,
                "type" => "USER"
            },
            "group-SysOps" => {
                "name" => "SysOps",
                "realm" => undefined,
                "type" => "GROUP"
            }
        }
    }
}
Add a New Role

This procedure shows how to add a role-mapping entry for a role. This must be done before the role can be configured.

Use the add operation to add a new role configuration.

/core-service=management/access=authorization/role-mapping=ROLENAME:add
Add a Group as Included in a Role

This procedure shows how to add a group to the included list of a role.

If no configuration for a role has been done, then a role-mapping entry for it must be done first.

Use the add operation to add a group entry to the includes list of the role.

/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:add(name=GROUPNAME, type=GROUP)
  • ROLENAME is the name of the role being configured, such as Auditor.
  • GROUPNAME is the name of the group being added to the include list, such as investigators.
  • ALIAS is a unique name for this mapping. Red Hat recommends that you use a naming convention for your aliases, such as group-GROUPNAME (for example, group-investigators).

Example: Management CLI Command for Adding a Group as Included in a Role

/core-service=management/access=authorization/role-mapping=Auditor/include=group-investigators:add(name=investigators, type=GROUP)

Add a Group as Excluded in a Role

This procedure shows how to add a group to the excluded list of a role.

If no configuration for a role has been done, then a role-mapping entry for it must be created first.

Use the add operation to add a group entry to the excludes list of the role.

/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:add(name=GROUPNAME, type=GROUP)
  • ROLENAME is the name of the role being configured, such as Auditor.
  • GROUPNAME is the name of the group being added to the include list, such as supervisors.
  • ALIAS is a unique name for this mapping. Red Hat recommends that you use a naming convention for your aliases, such as group-GROUPNAME (for example, group-supervisors).

Example: Management CLI Command for Adding a Group as Excluded in a Role

/core-service=management/access=authorization/role-mapping=Auditor/exclude=group-supervisors:add(name=supervisors, type=GROUP)

Remove Group Role Include Configuration

This procedure shows how to remove a group include entry from a role mapping.

Use the remove operation to remove the entry.

/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:remove
  • ROLENAME is the name of the role being configured, such as Auditor.
  • ALIAS is a unique name for this mapping. Red Hat recommends that you use a naming convention for your aliases, such as group-GROUPNAME (for example, group-investigators).

Example: Management CLI Command for Removing Group Role Include Configuration

/core-service=management/access=authorization/role-mapping=Auditor/include=group-investigators:remove

Note

Removing the group from the list of includes does not remove the group from the system, nor does it guarantee that the role will not be assigned to users in this group. The role might still be assigned to users in the group individually.

Remove a User Group Exclude Entry

This procedure shows how to remove a group exclude entry from a role mapping.

Use the remove operation to remove the entry.

/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:remove
  • ROLENAME is the name of the role being configured, such as Auditor.
  • ALIAS is a unique name for this mapping. Red Hat recommends that you use a naming convention for your aliases, such as group-GROUPNAME (for example, group-supervisors).
/core-service=management/access=authorization/role-mapping=Auditor/exclude=group-supervisors:remove
Note

Removing the group from the list of excludes does not remove the group from the system. It also does not guarantee the role will be assigned to members of the group. Roles might still be excluded based on group membership.

3.5.7. Using RBAC with LDAP

The basics of using RBAC with LDAP as well as how to configure JBoss EAP to use RBAC with LDAP are covered in the LDAP and RBAC section of the JBoss EAP How to Configure Identity Management Guide.

3.5.8. Scoped Roles

Scoped roles are user-defined roles that grant the permissions of one of the standard roles but only for one or more specified server groups or hosts in an JBoss EAP managed domain. Scoped roles allow for management users to be granted permissions that are limited to only those server groups or hosts that are required.

Important

Scoped roles can be created by users assigned the Administrator or SuperUser roles.

They are defined by five characteristics:

  • A unique name.
  • The standard roles which it is based on.
  • If it applies to server groups or hosts.
  • The list of server groups or hosts that it is restricted to.
  • If all users are automatically included. This defaults to false.

Once created a scoped role can be assigned to users and groups the same way that the standard roles are.

Creating a scoped role does not allow for defining new permissions. Scoped roles can only be used to apply the permissions of an existing role in a limited scope. For example, a scoped role could be created based on the Deployer role which is restricted to a single server group.

There are only two scopes that roles can be limited to:

Host-scoped roles
A role that is host-scoped restricts the permissions of that role to one or more hosts. This means access is provided to the relevant /host=*/ resource trees but resources that are specific to other hosts are hidden.
Server-group-scoped roles
A role that is server-group-scoped restricts the permissions of that role to one or more server groups. Additionally the role permissions will also apply to the profile, socket binding group, server configuration, and server resources that are associated with the specified server-groups. Any sub-resources within any of those that are not logically related to the server-group will not be visible to the user.
Important

Some resources are non-addressable to server-group and host scoped roles in order to provide a simplified view of the management model to improve usability. This is distinct from resources that are non-addressable to protect sensitive data.

For host scoped roles this means that resources in the /host=* portion of the management model will not be visible if they are not related to the server groups specified for the role.

For server-group scoped roles, this means that resources in the profile, socket-binding-group, deployment, deployment-overlay, server-group, server-config and server portions of the management model will not be visible if they are not related to the server groups specified for the role.

3.5.8.1. Configuring Scoped Roles from the Management CLI

Important

Only users in the SuperUser or Administrator roles can perform this configuration.

Add a New Scoped Role

To add a new scoped role, the following operations must be done:

/core-service=management/access=authorization/role-mapping=NEW-SCOPED-ROLE:add
/core-service=management/access=authorization/server-group-scoped-role=NEW-SCOPED-ROLE:add(base-role=BASE-ROLE, server-groups=[SERVER-GROUP-NAME])

Replace NEW-SCOPED-ROLE, BASE-ROLE, and SERVER-GROUP-NAME with the proper information.

Viewing and Editing a Scoped Role Mapping

A scoped role’s details, including members, can be viewed by using the following command:

/core-service=management/access=authorization/role-mapping=NEW-SCOPED-ROLE:read-resource(recursive=true)

Replace NEW-SCOPED-ROLE with the proper information.

To edit a scoped role’s details, the write-attribute command may be used. For example:

/core-service=management/access=authorization/role-mapping=NEW-SCOPED-ROLE:write-attribute(name=include-all, value=true)

Replace NEW-SCOPED-ROLE with the proper information.

Delete a Scoped Role
/core-service=management/access=authorization/role-mapping=NEW-SCOPED-ROLE:remove
/core-service=management/access=authorization/server-group-scoped-role=NEW-SCOPED-ROLE:remove

Replace NEW-SCOPED-ROLE with the proper information.

Important

A scoped role cannot be deleted if users or groups are assigned to it. Remove the role assignments first, and then delete it.

Adding and Removing Users

Adding and removing users to and from scoped roles follows the same process as adding and removing standard roles.

3.5.8.2. Configuring Scoped Roles from the Management Console

Important

Only users in the SuperUser or Administrator roles can perform this configuration.

Scoped role configuration in the management console can be found by following these steps:

  1. Log in to the management console
  2. Click on the Access Control tab
  3. Click on the Roles menu on the left and all roles, including scoped roles, are displayed.

The following procedures show how to perform configuration tasks for scoped roles.

Add a New Scoped Role
  1. Log in to the management console.
  2. Click on the Access Control tab.
  3. Click on the Roles menu on the left.
  4. Click Add.
  5. Specify the following details:

    • Name, the unique name for the new scoped role.
    • Base Role, the role which this role will base its permissions on.
    • Type, whether this role will be restricted to hosts or server groups.
    • Scope, the list of hosts or server groups that the role is restricted to. Multiple entries can be selected.
    • Include All, should this role automatically include all users. Defaults to no.
  6. Click Save and the dialog will close and the newly created role will appear in the table.
Edit a Scoped Role
  1. Log in to the management console.
  2. Click on the Access Control tab.
  3. Click on the Roles menu on the left.
  4. Click on the desired scoped role to edit and click Edit.
  5. Update the desired details to change and click the Save button.
View Scoped Role Members
  1. Log in to the management console.
  2. Click on the Access Control tab.
  3. Click on the Roles menu on the left.
  4. Click on the desired scoped role and choose Include or Exclude to view the included or excluded members.
Delete a Scoped Role
  1. Log in to the management console.
  2. Click on the Access Control tab.
  3. Click on the Roles menu on the left.
  4. Click on the desired scoped role, click the drop-down arrow next to the Edit button and click Remove.
  5. Click Confirm. The dialog closes and the role is removed.
Important

A scoped role cannot be deleted if users or groups are assigned to it. Remove the role assignments first, and then delete it.

Adding and Removing Users

Adding and removing users to and from scoped roles follows the same process as adding and removing standard roles. To update a user’s scoped roles:

  1. Log in to the management console.
  2. Click on the Access Control tab.
  3. Click on the Roles menu on the left.
  4. Click on the desired scoped role and choose Include or Exclude to view the included or excluded members.
  5. To add a member, click Add, choose the member to include or exclude, and click Save.
  6. To remove a member, select the desired member to remove and click Remove.

3.5.9. Configuring Constraints

3.5.9.1. Configure Sensitivity Constraints

Each sensitivity constraint defines a set of resources that are considered sensitive. A sensitive resource is generally one that either should be secret, like passwords, or one that will have serious impact on the server, like networking, JVM configuration, or system properties. The access control system itself is also considered sensitive. Resource sensitivity limits which roles are able to read, write or address a specific resource.

Sensitivity constraint configuration is at /core-service=management/access=authorization/constraint=sensitivity-classification.

Within the management model each sensitivity constraint is identified as a classification. The classifications are then grouped into types. Each classification has an applies-to element which is a list of path patterns to which the classifications configuration applies.

To configure a sensitivity constraint, use the write-attribute operation to set the configured-requires-read, configured-requires-write, or configured-requires-addressable attribute. To make that type of operation sensitive set the value of the attribute to true, otherwise to make it nonsensitive set it to false. By default these attributes are not set and the values of default-requires-read, default-requires-write, and default-requires-addressable are used. Once the configured attribute is set it is that value that is used instead of the default. The default values cannot be changed.

Example: Make Reading System Properties a Sensitive Operation

/core-service=management/access=authorization/constraint=sensitivity-classification/type=core/classification=system-property:write-attribute(name=configured-requires-read,value=true)

Example: Result

/core-service=management/access=authorization/constraint=sensitivity-classification/type=core/classification=system-property:read-resource

{
    "outcome" => "success",
    "result" => {
        "configured-requires-addressable" => undefined,
        "configured-requires-read" => true,
        "configured-requires-write" => undefined,
        "default-requires-addressable" => false,
        "default-requires-read" => false,
        "default-requires-write" => true,
        "applies-to" => {
            "/core-service=platform-mbean/type=runtime" => undefined,
            "/system-property=*" => undefined,
            "/" => undefined
        }
    }
}

The roles, and the respective operations that they are able to perform, depend on the configuration of the attributes. This is summarized in the following table:

Table 3.2. Sensitivity Constraint Configuration Outcomes

Valuerequires-readrequires-writerequires-addressable

true

Read is sensitive. Only Auditor, Administrator, SuperUser can read.

Write is sensitive. Only Administrator and SuperUser can write.

Addressing is sensitive. Only Auditor, Administrator, SuperUser can address.

false

Read is not sensitive. Any management user can read.

Write is not sensitive. Only Maintainer, Administrator and SuperUser can write. Deployer can also write the resource is an application resource.

Addressing is not sensitive. Any management user can address.

3.5.9.2. List Sensitivity Constraints

You can see a list of the available sensitivity constraints directly from the JBoss EAP management model using the following management CLI command:

/core-service=management/access=authorization/constraint=sensitivity-classification:read-resource(include-runtime=true,recursive=true)

3.5.9.3. Configure Application Resource Constraints

Each application resource constraint defines a set of resources, attributes and operations that are usually associated with the deployment of applications and services. When an application resource constraint is enabled management users of the Deployer role are granted access to the resources that it applies to.

Application constraint configuration is at /core-service=management/access=authorization/constraint=application-classification/.

Each application resource constraint is identified as a classification. The classifications are then grouped into types. Each classification has an applies-to element which is a list of path patterns to which the classifications configuration applies.

By default the only application resource classification that is enabled is core. Core includes deployments, deployment overlays, and the deployment operations.

To enable an application resource, use the write-attribute operation to set the configured-application attribute of the classification to true. To disable an application resource, set this attribute to false. By default these attributes are not set and the value of default-application attribute is used. The default value cannot be changed.

Example: Enabling the logger-profile Application Resource Classification

/core-service=management/access=authorization/constraint=application-classification/type=logging/classification=logging-profile:write-attribute(name=configured-application,value=true)

Example: Result

/core-service=management/access=authorization/constraint=application-classification/type=logging/classification=logging-profile:read-resource

{
    "outcome" => "success",
    "result" => {
        "configured-application" => true,
        "default-application" => false,
        "applies-to" => {"/subsystem=logging/logging-profile=*" => undefined}
    }
}
Important

Application resource constraints apply to all resources that match its configuration. For example, it is not possible to grant a Deployer user access to one datasource resource but not another. If this level of separation is required then it is recommended to configure the resources in different server groups and create different scoped Deployer roles for each group.

3.5.9.4. List Application Resource Constraints

You can see a list of the available application resource constraints directly from the JBoss EAP management model using the following management CLI command:

/core-service=management/access=authorization/constraint=application-classification:read-resource(include-runtime=true,recursive=true)

3.5.9.5. Configure the Vault Expression Constraint

By default, reading and writing vault expressions are sensitive operations. Configuring the vault expression constraint allows either or both of those operations to be set to nonsensitive. Changing this constraint allows a greater number of roles to read and write vault expressions.

The vault expression constraint is found at /core-service=management/access=authorization/constraint=vault-expression.

To configure the vault expression constraint, use the write-attribute operation to set the attributes of configured-requires-write and configured-requires-read to true or false. By default these are not set and the values of default-requires-read and default-requires-write are used. The default values cannot be changed.

Example: Making Writing to Vault Expressions a Nonsensitive Operation

/core-service=management/access=authorization/constraint=vault-expression:write-attribute(name=configured-requires-write,value=false)

Example: Result

/core-service=management/access=authorization/constraint=vault-expression:read-resource

{
    "outcome" => "success",
    "result" => {
        "configured-requires-read" => undefined,
        "configured-requires-write" => false,
        "default-requires-read" => true,
        "default-requires-write" => true
    }
}

The roles, and the respective vault expressions that they will be able to read and write, depend on the configuration of the attributes. This is summarized in the following table:

Table 3.3. Vault Expression Constraint Configuration Outcomes

Valuerequires-readrequires-write

true

Read operation is sensitive. Only Auditor, Administrator, and SuperUser can read.

Write operation is sensitive. Only Administrator and SuperUser can write.

false

Read operation is not sensitive. All management users can read.

Write operation is not sensitive. Monitor, Administrator, and SuperUser can write. Deployer can also write if the vault expression is in an application resource.