[[Security_Realms]]
= Security Realms

Within WildFly we make use of security realms to secure access to the
management interfaces, these same realms are used to secure inbound
access as exposed by JBoss Remoting such as remote JNDI and EJB access,
the realms are also used to define an identity for the server - this
identity can be used for both inbound connections to the server and
outbound connections being established by the server.

[[general-structure]]
== General Structure

The general structure of a management realm definition is: -

[source,xml,options="nowrap"]
----
<security-realm name="ManagementRealm">
   <plug-ins></plug-ins>
   <server-identities></server-identities>
   <authentication></authentication>
   <authorization></authorization>
</security-realm>
----

* `plug-ins` - This is an optional element that is used to define
modules what will be searched for security realm PlugInProviders to
extend the capabilities of the security realms.
* `server-identities` - An optional element to define the identity of
the server as visible to the outside world, this applies to both inbound
connection to a resource secured by the realm and to outbound
connections also associated with the realm.

One example is the SSL identity of the server, for inbound connections
this will control the identity of the server as the SSL connection is
established, for outbound connections this same identity can be used
where CLIENT-CERT style authentication is being performed.

A second example is where the server is establishing an outbound
connection that requires username / password authentication - this
element can be used to define that password.

* `authentication` - This is probably the most important element that
will be used within a security realm definition and mostly applies to
inbound connections to the server, this element defines which backing
stores will be used to provide the verification of the inbound
connection.

This element is optional as there are some scenarios where it will not
be required such as if a realm is being defined for an outbound
connection using a username and password.

* `authorization` - This is the final optional element and is used to
define how roles are loaded for an authenticated identity. At the moment
this is more applicable for realms used for access to EE deployments
such as web applications or EJBs but this will also become relevant as
we add role based authorization checks to the management model.

[[using-a-realm]]
== Using a Realm

After a realm has been defined it needs to be associated with an inbound
or outbound connection for it to be used, the following are some
examples where these associations are used within the WildFly {wildflyVersion}
configuration.

[[inbound-connections]]
=== Inbound Connections

[[management-interfaces]]
==== Management Interfaces

Either within the `standalone.xml` or `host.xml` configurations the
security realms can be associated with the management interface as
follows:

[source,xml,options="nowrap"]
----
<http-interface security-realm="ManagementRealm">...</http-interface>
----

If the `security-realm` attribute is omitted or removed from the
interface definition it means that access to that interface will be
unsecured.

[NOTE]

By default we do bind these interfaces to the loopback address so that
the interfaces are not accessible remotely out of the box, however do be
aware that if these interfaces are then unsecured any other local user
will be able to control and administer the WildFly installation.

[[remoting-subsystem]]
==== Remoting Subsystem

The Remoting subsystem exposes a connector to allow for inbound
comunications with JNDI and the EJB subsystem by default we associate
the `ApplicationRealm` with this connection.

[source,xml,options="nowrap"]
----
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
  <endpoint worker="default"/>
  <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
</subsystem>
----

[[outbound-connections]]
=== Outbound Connections

==== Remoting Subsystem

Outbound connections can also be defined within the Remoting subsystem,
these are typically used for remote EJB invocations from one AS server
to another, in this scenario the security realm is used to obtain the
server identity either it's password for X.509 certificate and possibly
a trust store to verify the certificate of the remote host.

[NOTE]

Even if the referenced realm contains username and password
authentication configuration the client side of the connection will NOT
use this to verify the remote server.

[source,xml,options="nowrap"]
----
<remote-outbound-connection name="remote-ejb-connection"
                            outbound-socket-binding-ref="binding-remote-ejb-connection"
                            username="user1"
                            security-realm="PasswordRealm">
----

[IMPORTANT]

The security realm is only used to obtain the password for this example,
as you can see here the username is specified separately.

[[slave-host-controller]]
==== Slave Host Controller

When running in domain mode slave host controllers need to establish a
connection to the native interface of the master domain controller so
these also need a realm for the identity of the slave.

[source,xml,options="nowrap"]
----
<domain-controller>
  <remote host="${jboss.domain.master.address}" port="${jboss.domain.master.port:9999}" security-realm="ManagementRealm"/>
</domain-controller>
----

[TIP]

By default when a slave host controller authenticates against the master
domain controller it uses its configured name as its username. If you
want to override the username used for authentication a `username`
attribute can be added to the `<remote />` element.

[[security-realm-authentication]]
== Authentication

One of the primary functions of the security realms is to define the
user stores that will be used to verify the identity of inbound
connections, the actual approach taken at the transport level is based
on the capabilities of these backing store definitions. The security
realms are used to secure inbound connections for both the http
management interface and for inbound remoting connections for both the
native management interface and to access other services exposed over
remoting - because of this there are some small differences between how
the realm is used for each of these.

At the transport level we support the following authentication mechanisms.

[cols=",",options="header"]
|========================
|HTTP |Remoting (SASL)
|None |Anonymous
|N/A |JBoss Local User
|Digest |Digest
|Basic |Plain
|Client Cert |Client Cert
|========================

The most notable are the first two in this list as they need some
additional explanation - the final 3 are fairly standard mechanisms.

If either the http interface, the native interface or a remoting
connection are difined *without* a security realm reference then they
are effectively unsecured, in the case of the http interface this means
that no authentication will be performed on the incoming connection -
for the remoting connections however we make use of SASL so require at
least one authentication mechanism so make use of the anonymous
mechanism to allow a user in without requiring a validated
authentication process.

The next mechanism 'JBoss Local User' is specific to the remoting
connections - as we ship WildFly secured by default we wanted a way to
allow users to connect to their own AS installation after it is started
without mandating that they define a user with a password - to
accomplish this we have added the 'JBoss Local User' mechanism. This
mechanism makes the use of tokens exchanged on the filesystem to prove
that the client is local to the AS installation and has the appropriate
file permissions to read a token written by the AS to file. As this
mechanism is dependent on both server and client implementation details
it is only supported for the remoting connections and not the http
connections - at some point we may review if we can add support for this
to the http interface but we would need to explore the options available
with the commony used web browsers that are used to communicate with the
http interface.

The Digest mechanism is simply the HTTP Digest / SASL Digest mechanism
that authenticates the user by making use of md5 hashed including nonces
to avoid sending passwords in plain text over the network - this is the
preferred mechanism for username / password authentication.

The HTTP Basic / SASL Plain mechanism is made available for times that
Digest can not be used but effectively this means that the users
password will be sent over the network in the clear unless SSL is
enabled.

The final mechanism Client-Cert allows X.509 certificates to be used to
verify the identity of the remote client.

[IMPORTANT]

One point bearing in mind is that it is possible that an association
with a realm can mean that a single incoming connection has the ability
to choose between one or more authentication mechanisms. As an example
it is possible that an incoming remoting connection could choose between
'Client Cert', A username password mechanism or 'JBoss Local User' for
authentication - this would allow say a local user to use the local
mechanism, a remote user to supply their username and password whilst a
remote script could make a call and authenticate using a certificate.

[[authorization]]
== Authorization

The actual security realms are not involved in any authorization
decisions. However, they can be configured to load a user's roles, which
will subsequently be used to make authorization decisions - when
references to authorization are seen in the context of security realms,
it is this loading of roles that is being referred to.

For the loading of roles, the process is split out to occur after the
authentication step so after a user has been authenticated, a second
step will occur to load the roles based on the username they used to
authenticate with.

[[out-of-the-box-configuration]]
== Out Of The Box Configuration

Before describing the complete set of configuration options available
within the realms, we will look at the default configuration, as for
most users, that is going to be the starting point before customising
further.

[IMPORTANT]

The examples here are taken from the standalone configuration. However,
the descriptions are equally applicable to domain mode. One point worth
noting is that all security realms defined in the `host.xml` are
available to be referenced within the domain configuration for the
servers running on that host controller.

[[management-realm]]
=== Management Realm

[source,xml,options="nowrap"]
----
<security-realm name="ManagementRealm">
  <authentication>
    <local default-user="$local"/>
    <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
  </authentication>
</security-realm>
----

The realm `ManagementRealm` is the simplest realm within the default
configuration. This realm simply enables two authentication mechanisms,
the local mechanism and username/password authentication which will be
using Digest authentication.

* local

When using the local mechanism, it is optional for remote clients to
send a username to the server. This configuration specifies that where
clients do not send a username, it will be assumed that the clients
username is `$local` - the `<local />` element can also be configured to
allow other usernames to be specified by remote clients. However, for
the default configuration, this is not enabled so is not supported.

* properties

For username / password authentication the users details will be loaded
from the file `mgmt-users.properties` which is located in \{
`jboss.home}/standalone/configuration` or \{
`jboss.home}/domain/configuration` depending on the running mode of the
server.

Each user is represented on their own line and the format of each line
is `username=` `HASH` where `HASH` is a pre-prepared hash of the users
password along with their username and the name of the realm which in
this case is `ManagementRealm`.

[TIP]

You do not need to worry about generating the entries within the
properties file as we provide a utility `add-user.sh` or `add-user.bat`
to add the users, this utility is described in more detail below.

[WARNING]

By pre-hashing the passwords in the properties file it does mean that if
the user has used the same password on different realms then the
contents of the file falling into the wrong hands does not nescesarily
mean all accounts are compromised. *HOWEVER* the contents of the files
do still need to be protected as they can be used to access any server
where the realm name is the same and the user has the same username and
password pair.

=== Application Realm

[source,xml,options="nowrap"]
----
<security-realm name="ApplicationRealm">
  <authentication>
    <local default-user="$local" allowed-users="*"/>
    <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
  </authentication>
  <authorization>
    <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
  </authorization>
</security-realm>
----

The realm `ApplicationRealm` is a slightly more complex realm as this is
used for both

==== Authentication

The authentication configuration is very similar to the
`ManagementRealm` in that it enabled both the local mechanism and a
username/password based Digest mechanism.

* local

The local configuration is similar to the `ManagementRealm` in that
where the remote user does not supply a username it will be assumed that
the username is `$local`, however in addition to this there is now an
`allowed-users` attribute with a value of `'*'` - this means that the
remote user can specify any username and it will be accepted over the
local mechanism provided that the local verification is a success.

[IMPORTANT]

To restrict the usernames that can be specified by the remote user a
comma separated list of usernames can be specified instead within the
`allowed-users` attribute.

* properties

The properties definition works in exactly the same way as the
definition for `ManagementRealm` except now the properties file is
called `application-users.properties`.

==== Authorization

The contents of the `Authorization` element are specific to the
`ApplicationRealm`, in this case a properties file is used to load a
users roles.

The properties file is called `application-roles.properties` and is
located in \{ `jboss.home}/standalone/configuration` or \{
`jboss.home}/domain/configuration` depending on the running mode of the
server. The format of this file is `username=` `ROLES` where _ROLES_ is
a comma separated list of the users roles.

[TIP]

As the loading of a users roles is a second step this is where it may be
desirable to restrict which users can use the local mechanism so that
some users still require username and password authentication for their
roles to be loaded.

[[other-security-domain]]
==== other security domain

[source,xml,options="nowrap"]
----
<security-domain name="other" cache-type="default">
  <authentication>
    <login-module code="Remoting" flag="optional">
      <module-option name="password-stacking" value="useFirstPass"/>
    </login-module>
    <login-module code="RealmDirect" flag="required">
      <module-option name="password-stacking" value="useFirstPass"/>
    </login-module>
  </authentication>
</security-domain>
----

When applications are deployed to the application server they are
associated with a security domain within the security subsystem, the
`other` security domain is provided to work with the `ApplicationRealm`,
this domain is defined with a pair of login modules Remoting and
RealmDirect.

* Remoting

The `Remoting` login module is used to check if the request currently
being authenticated is a request received over a Remoting connection, if
so the identity that was created during the authentication process is
used and associated with the current request.

If the request did not arrive over a Remoting connection this module
does nothing and allows the JAAS based login to continue to the next
module.

* RealmDirect

The `RealmDirect` login module makes use of a security realm to
authenticate the current request if that did not occur in the `Remoting`
login module and then use the realm to load the users roles, by default
this login module assumes the realm to use is called `ApplicationRealm`
although other names can be overridden using the "realm" module-option.

The advantage of this approach is that all of the backing store
configuration can be left within the realm with the security domain just
delegating to the realm.

[[add-user.sh]]

:leveloffset: +1

include::add-user-utility.adoc[]

:leveloffset: -1

[[jmx-security]]
== JMX Security

When configuring the security realms remote access to the server's
MBeanServer needs a special mention. When running in standalone mode the
following is the default configuration:

[source,xml,options="nowrap"]
----
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
  ...
  <remoting-connector/>
</subsystem>
----

With this configuration remote access to JMX is provided over the http
management interface, this is secured using the realm `ManagementRealm`,
this means that any user that can connect to the native interface can
also use this interface to access the MBeanServer - to disable this just
remove the `<remoting-connector />` element.

In domain mode it is slightly more complicates as the native interface
is exposed by the host controller process however each application
server is running in it's own process so by default remote access to JMX
is disabled.

[source,xml,options="nowrap"]
----
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
  <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
</subsystem>
----

[source,xml,options="nowrap"]
----
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
  ...
  <!--<remoting-connector use-management-endpoint="false"/>-->
</subsystem>
----

To enable remote access to JMX uncomment the `<remoting-connector />`
element however be aware that this will make the MBeanServer accessible
over the same Remoting connector used for remote JNDI and EJB access -
this means that any user that can authenticate against the realm
`ApplicationRealm` will be able to access the MBeanServer.

[IMPORTANT]

The following Jira issue is currently outstanding to allow access to the
individual MBeanServers by proxying through the host controllers native
interface https://issues.redhat.com/browse/WFCORE-2584[WFCORE-2584], if this is
a feature you would use please add your vote to the issue.

:leveloffset: +1

include::Security_Realms_Detailed_Configuration.adoc[]

include::Security_Realms_Plugins.adoc[]

include::Security_Realms_Examples.adoc[]

:leveloffset: -1
