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 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: Set http-authentication-factory to use management-http-authentication : Set sasl-authentication-factory to use management-sasl-authentication : Undefine security-realm : Reload JBoss EAP for the changes to take affect: 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. The management-http-authentication http-authentication-factory, is configured to use the ManagementDomain security domain. 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. 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 The default sasl-authentication-factory is management-sasl-authentication . 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 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 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 . Create an http-authentication-factory or sasl-authentication-factory . Example: http-authentication-factory Example: sasl-authentication-factory Add pattern-filter to the configured configurable-sasl-server-factory . Example: Add GSSAPI to the Configured configurable-sasl-server-factory 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. Update the management interfaces to use your http-authentication-factory or sasl-authentication-factory . Example: Update http-authentication-factory Example: Update sasl-authentication-factory 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 HTTP 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 HTTP 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 see Silent authentication section. Silent authentication must be added to a sasl-authentication-factory . To add silent authentication to an existing sasl-authentication-factory : To create a new sasl-server-factory with silent authentication: 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 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 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 Scenario No access=identity definition access=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. 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 . 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:client:1.2"> <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> Use the Elytron Client configuration file with management CLI script. 3.2. Identity Propagation and Forwarding with Elytron 3.2.1. Propagating Security Identities for Remote Calls JBoss EAP 7.1 introduced 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 Jakarta Enterprise Beans to a remote Jakarta Enterprise Beans. It returns a string containing the name of the Principal that called the remote Jakarta Enterprise Beans along with the user's authorized role information. The example consists of the following components. A secured Jakarta Enterprise Beans that contains a single method, accessible by all users, that returns authorization information about the caller. An intermediate Jakarta Enterprise Beans that contains a single method. It makes use of a remote connection and invokes the method on the secured Jakarta Enterprise Beans. A remote standalone client application that invokes the intermediate Jakarta Enterprise Beans. 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. review the example application code that uses the WildFlyInitialContextFactory to look up and invoke the remote Jakarta Enterprise Beans. Configure the Server for Security Propagation Configure the ejb3 subsystem to use the Elytron 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> 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. This adds the following authentication-client configuration to the elytron subsystem. <subsystem xmlns="urn:wildfly:elytron:4.0" 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> Add the remote destination outbound socket binding to the standard-sockets socket binding group. 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="USD{jboss.socket.binding.port-offset:0}"> .... <outbound-socket-binding name="ejb-outbound"> <remote-destination host="localhost" port="8080"/> </outbound-socket-binding> </socket-binding-group> Add the remote outbound connection and set the SASL authentication factory in the HTTP connector. 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> Configure the Elytron SASL authentication to use the PLAIN mechanism. This adds the following application-sasl-authentication configuration to the elytron subsystem. <subsystem xmlns="urn:wildfly:elytron:4.0" 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 Jakarta Enterprise Beans client application can use the WildFlyInitialContextFactory to look up and invoke the Jakarta Enterprise Beans proxy. The Jakarta Enterprise Beans 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.4. See that quickstart for a complete working example of security identity propagation. To invoke the Jakarta Enterprise Beans 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 Jakarta Enterprise Beans @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 Jakarta Enterprise Beans @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:client:1.2"> <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 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 This command adds the following simple-permission-mapper configuration to the elytron subsystem. Example: Simple Permission Mapper Configuration <mappers> <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-set name="login-permission"/> <permission-set name="default-permissions"/> <permission-set name="run-as-principal-permission"/> </permission-mapping> <permission-mapping match-all="true"> <permission-set name="login-permission"/> <permission-set name="default-permissions"/> </permission-mapping> </simple-permission-mapper> </mappers> <permission-sets> <permission-set name="login-permission"> <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/> </permission-set> <permission-set name="default-permissions"> <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-set> <permission-set name="run-as-principal-permission"> <permission class-name="org.wildfly.security.auth.permission.RunAsPrincipalPermission" target-name="*"/> </permission-set> </permission-sets> Note The login-permission and default-permissions permission sets are already present in the default configuration. 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. Creating a case-principal-transformer to change the case characters of your principal username The elytron subsystem includes the case-principal-transformer principal transformer. You can use this principal transformer to change a principal's username to either uppercase or lowercase characters. The case-principal-transformer principal transformer includes the upper-case attribute that is set as true by default. To demonstrate a use case for case-principal-transformer , consider that you are using an authentication mechanism to map a principal to a security realm. A realm mapper manipulates the mapped principal to identify a security realm and load one of its identities. The authentication mechanism passes the identity to a post-realm mapping stage and to a final principal transformation stage. Subsequently, the authentication mechanism verifies the identity for authentication purposes. You can use a case-principal-transformer principal transformer to convert the character case format of your mapped principal. The example in the procedure uses the case-principal-transformer in the context of a security domain. You can also use the principal transformer inline with the following authentication policies: http-authentication-factory sasl-authentication-factory ssl-context aggregate-realm Procedure Add the case-principal-transformer to the elytron subsystem, and choose the character case for the username. To change the username of a transformer to uppercase characters, do not change the default upper-case attribute value. Example showing <transformer_name> added to the elytron subsystem with the default upper-case attribute setting defined: Alternatively, you can truncate the command syntax to use the default upper-case attribute value: To change the username of a transformer to lowercase characters, set the upper-case attribute to false . Example showing <transformer_name> added to the elytron subsystem with the upper-case attribute set to false : Optional: Use the elytron subsystem to configure your principal transformer. The following example configured a principal transformer to the default ApplicationDomain configuration that was provided by the elytron subsystem. Elytron applies the default ApplicationDomain configuration to a pre-realm-principal-transformer : Note You can configure a post-realm-principal-transformer to use the ApplicationDomain configuration after a security realm has been identified by a realm mapper. Additional resources For information about the upper-case attribute, see Table A.26 case-principal-transformer attributes . 3.2.4. 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.5. 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 Jakarta Enterprise Beans Calls By default, when you make a remote call to a Jakarta Enterprise Beans 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 Jakarta Enterprise Beans within the security context of a different identity. You can use the Elytron API to switch identities in server-to-server Jakarta Enterprise Beans 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 Jakarta Enterprise Beans. 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 Jakarta Enterprise Beans 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: Run the add-user.sh or add-user.bat command. Choose whether to add a management user or application user. 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. 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: 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: Create a security realm with JAAS authentication. Update the http-interface management interface to use new security realm. 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). 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 USDlocal 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 USDlocal , 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 . 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. 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 . 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="USDlocal"/> </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. The valid policy names are rejecting and permissive . Example: Management CLI Command for Rejecting Permission Combination Policy 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="USDlocal"/> </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: Use the read-resource operation of a specified role-mapping to get the full details of a specific role: 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. ROLENAME is the name of the role that the new mapping is for, such as Auditor . Example: Management CLI Command for New Role Configuration 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. 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 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. 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 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. 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 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. 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 ). 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: 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: Use the read-resource operation of a specified role-mapping to get the full details of a specific role: 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. 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. 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 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. 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 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. 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 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. 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 ). 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: 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: Replace NEW-SCOPED-ROLE with the proper information. To edit a scoped role's details, the write-attribute command may be used. For example: Replace NEW-SCOPED-ROLE with the proper information. Delete a Scoped Role 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: Log in to the management console. Click on the Access Control tab. Click on Roles to view all roles, including scoped roles. The following procedures show how to perform configuration tasks for scoped roles. Add a New Scoped Role Log in to the management console. Click on the Access Control tab. Select Roles and click the Add ( + ) button. Choose Host Scoped Role or Server Group Scoped Role . 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. Hosts or Server Groups : The list of hosts or server groups that the role is restricted to, depending on the type of scoped role being added. Multiple entries can be selected. Include All : Whether this role should automatically include all users. Defaults to OFF . Click Add to create the new role. Edit a Scoped Role Log in to the management console. Click on the Access Control tab. Click on the Roles menu on the left. Click on the desired scoped role to edit and click Edit . Update the desired details to change and click the Save button. View Scoped Role Members Log in to the management console. Click on the Access Control tab. Click on the Roles menu on the left. Click on the desired scoped role to view the included and excluded members. Delete a Scoped Role Log in to the management console. Click on the Access Control tab. Click on the Roles menu on the left. Click on the desired scoped role and click Remove from the drop down. Click Yes to remove the role and all of its assignments. 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: Log in to the management console. Click on the Access Control tab. Click on the Roles menu on the left and click on the desired scoped role. Select the Plus ( + ) button to include a member or the Minus ( - ) button to exclude a member. 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 Example: Result 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 Value requires-read requires-write requires-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: 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 Example: Result 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: 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 Example: Result 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 Value requires-read requires-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.

Commands:
/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 }
/core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=management-http-authentication)
/core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade.sasl-authentication-factory, value=management-sasl-authentication)
/core-service=management/management-interface=http-interface:undefine-attribute(name=security-realm)
reload
/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" } }
/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 } }
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" } } }
<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>
/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 } }
/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" } }
/subsystem=elytron/identity-realm=local:read-resource() { "outcome" => "success", "result" => { "attribute-name" => undefined, "attribute-values" => undefined, "identity" => "USDlocal" } }
/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}]}])
/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}]}])
/subsystem=elytron/configurable-sasl-server-factory=configured:list-add(name=filters, value={pattern-filter=GSSAPI})
/core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=example-http-auth) reload
/core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade.sasl-authentication-factory, value=example-sasl-auth) reload
/subsystem=elytron/sasl-authentication-factory=example-sasl-auth:list-add(name=mechanism-configurations, value={mechanism-name=JBOSS-LOCAL-USER, realm-mapper=local}) reload
/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
/core-service=management/access=identity:add(security-domain=exampleSD)
:whoami { "outcome" => "success", "result" => {"identity" => {"username" => "user1"}} }
<configuration> <authentication-client xmlns="urn:elytron:client:1.2"> <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>
./jboss-cli.sh -c -Dwildfly.config.url=/path/to/custom-config.xml
/subsystem=ejb3/application-security-domain=quickstart-domain:add(security-domain=ApplicationDomain)
<subsystem xmlns="urn:jboss:domain:ejb3:5.0"> . <application-security-domains> <application-security-domain name="quickstart-domain" security-domain="ApplicationDomain"/> </application-security-domains> </subsystem>
/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}])
<subsystem xmlns="urn:wildfly:elytron:4.0" 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>
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=ejb-outbound:add(host=localhost,port=8080)
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="USD{jboss.socket.binding.port-offset:0}"> . <outbound-socket-binding name="ejb-outbound"> <remote-destination host="localhost" port="8080"/> </outbound-socket-binding> </socket-binding-group>
/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)
<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>
/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}]}])
<subsystem xmlns="urn:wildfly:elytron:4.0" 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>
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()); } }
@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); } } }
@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(); } }
<?xml version="1.0" encoding="UTF-8"?> <configuration> <authentication-client xmlns="urn:elytron:client:1.2"> <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>
/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}])
<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>
/subsystem=elytron/permission-set=run-as-principal-permission:add(permissions=[{class-name="org.wildfly.security.auth.permission.RunAsPrincipalPermission",target-name="*"}]) /subsystem=elytron/simple-permission-mapper=auth-forwarding-permission-mapper:add(permission-mappings=[{principals=["anonymous"]},{principals=["theserver1"],permission-sets=[{permission-set=login-permission},{permission-set=default-permissions},{permission-set=run-as-principal-permission}]},{match-all=true,permission-sets=[{permission-set=login-permission},{permission-set=default-permissions}]}]
<mappers> <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-set name="login-permission"/> <permission-set name="default-permissions"/> <permission-set name="run-as-principal-permission"/> </permission-mapping> <permission-mapping match-all="true"> <permission-set name="login-permission"/> <permission-set name="default-permissions"/> </permission-mapping> </simple-permission-mapper> </mappers> <permission-sets> <permission-set name="login-permission"> <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/> </permission-set> <permission-set name="default-permissions"> <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-set> <permission-set name="run-as-principal-permission"> <permission class-name="org.wildfly.security.auth.permission.RunAsPrincipalPermission" target-name="*"/> </permission-set> </permission-sets>
/subsystem=elytron/case-principal-transformer= <transformer_name> :add(upper-case="true")
/subsystem=elytron/case-principal-transformer= <transformer_name> :add()
/subsystem=elytron/case-principal-transformer= <transformer_name> :add(upper-case="false")
/subsystem=elytron/security-domain=ApplicationDomain:write-attribute(name=pre-realm-principal-transformer,value= <transformer_name> )
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); } }
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);
/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")])
/core-service=management/security-realm=SecurityDomainAuthnRealm:add /core-service=management/security-realm=SecurityDomainAuthnRealm/authentication=jaas:add(name=UsersLMDomain)
/core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=SecurityDomainAuthnRealm)
/core-service=management/security-realm=SecurityDomainAuthnRealm/authentication=jaas:write-attribute(name=assign-groups,value=true)
/core-service=management/access=authorization:write-attribute(name=provider, value=rbac) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } } reload
/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
/core-service=management/access=authorization:write-attribute(name=provider, value=simple)
<management> <access-control provider="rbac"> <role-mapping> <role name="SuperUser"> <include> <user name="USDlocal"/> </include> </role> </role-mapping> </access-control> </management>
/core-service=management/access=authorization:write-attribute(name=permission-combination-policy, value=POLICYNAME)
/core-service=management/access=authorization:write-attribute(name=permission-combination-policy, value=rejecting)
<access-control provider="rbac" permission-combination-policy="rejecting"> <role-mapping> <role name="SuperUser"> <include> <user name="USDlocal"/> </include> </role> </role-mapping> </access-control>
/core-service=management/access=authorization:read-children-names(child-type=role-mapping) { "outcome" => "success", "result" => [ "Administrator", "Deployer", "Maintainer", "Monitor", "Operator", "SuperUser" ] }
/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" } } } }
/core-service=management/access=authorization/role-mapping= ROLENAME :add
/core-service=management/access=authorization/role-mapping=Auditor:add
/core-service=management/access=authorization/role-mapping= ROLENAME /include= ALIAS :add(name= USERNAME , type=USER)
/core-service=management/access=authorization/role-mapping=Auditor/include=user-max:add(name=max, type=USER)
/core-service=management/access=authorization/role-mapping= ROLENAME /exclude= ALIAS :add(name= USERNAME , type=USER)
/core-service=management/access=authorization/role-mapping=Auditor/exclude=user-max:add(name=max, type=USER)
/core-service=management/access=authorization/role-mapping= ROLENAME /include= ALIAS :remove
/core-service=management/access=authorization/role-mapping=Auditor/include=user-max:remove
/core-service=management/access=authorization/role-mapping= ROLENAME /exclude= ALIAS :remove
/core-service=management/access=authorization/role-mapping=Auditor/exclude=user-max:remove
/core-service=management/access=authorization:write-attribute(name=use-identity-roles,value=true)
/core-service=management/access=authorization:read-children-names(child-type=role-mapping) { "outcome" => "success", "result" => [ "Administrator", "Deployer", "Maintainer", "Monitor", "Operator", "SuperUser" ] }
/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" } } } }
/core-service=management/access=authorization/role-mapping= ROLENAME :add
/core-service=management/access=authorization/role-mapping= ROLENAME /include= ALIAS :add(name= GROUPNAME , type=GROUP)
/core-service=management/access=authorization/role-mapping=Auditor/include=group-investigators:add(name=investigators, type=GROUP)
/core-service=management/access=authorization/role-mapping= ROLENAME /exclude= ALIAS :add(name= GROUPNAME , type=GROUP)
/core-service=management/access=authorization/role-mapping=Auditor/exclude=group-supervisors:add(name=supervisors, type=GROUP)
/core-service=management/access=authorization/role-mapping= ROLENAME /include= ALIAS :remove
/core-service=management/access=authorization/role-mapping=Auditor/include=group-investigators:remove
/core-service=management/access=authorization/role-mapping= ROLENAME /exclude= ALIAS :remove
/core-service=management/access=authorization/role-mapping=Auditor/exclude=group-supervisors:remove
/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 ])
/core-service=management/access=authorization/role-mapping= NEW-SCOPED-ROLE :read-resource(recursive=true)
/core-service=management/access=authorization/role-mapping= NEW-SCOPED-ROLE :write-attribute(name=include-all, value=true)
/core-service=management/access=authorization/role-mapping= NEW-SCOPED-ROLE :remove
/core-service=management/access=authorization/server-group-scoped-role= NEW-SCOPED-ROLE :remove
/core-service=management/access=authorization/constraint=sensitivity-classification/type=core/classification=system-property:write-attribute(name=configured-requires-read,value=true)
/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 } } }
/core-service=management/access=authorization/constraint=sensitivity-classification:read-resource(include-runtime=true,recursive=true)
/core-service=management/access=authorization/constraint=application-classification/type=logging/classification=logging-profile:write-attribute(name=configured-application,value=true)
/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} } }
/core-service=management/access=authorization/constraint=application-classification:read-resource(include-runtime=true,recursive=true)
/core-service=management/access=authorization/constraint=vault-expression:write-attribute(name=configured-requires-write,value=false)
/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 } }