[[authentication]]
== Authentication

Authentication identifies an individual. To gain access to restricted resources, a user must prove their identity, via
passwords, credentials, or some other means (typically referred to as authentication tokens).

[[realms]]
[float]
=== Realms

A _realm_ is an authentication mechanism, which Shield uses to resolve and authenticate users and their roles. Shield 
currently provides four realm types:

[horizontal]
_esusers_:: A native authentication system built into Shield and available by default. See <<esusers>>.
_LDAP_::    Authentication via an external Lightweight Directory Protocol. See <<ldap>>.
_Active Directory_::    Authentication via an external Active Directory service. See <<active_directory>>.
_PKI_:: Authentication through the use of trusted X.509 certificates. See <<pki>>.


NOTE: _esusers_, _LDAP_, and _Active Directory_ realms authenticate using the username and password authentication tokens.

Realms live within a _realm chain_. It is essentially a prioritized list of configured realms (typically of various types).
The order of the list determines the order in which the realms will be consulted. During the authentication process,
Shield will consult and try to authenticate the request one realm at a time. Once one of the realms successfully
authenticates the request, the authentication is considered to be successful and the authenticated user will be associated
with the request (which will then proceed to the authorization phase). If a realm cannot authenticate the request, the
next in line realm in the chain will be consulted. If all realms in the chain could not authenticate the request, the
authentication is then considered to be unsuccessful and an authentication error will be returned (as HTTP status code `401`).

NOTE: Shield attempts to authenticate to each configured realm sequentially. Some systems (e.g. Active Directory) have a 
temporary lock-out period after several successive failed login attempts. If the same username exists in multiple realms,
unintentional account lockouts are possible. For more information, please see <<trouble-shoot-active-directory, here>>.

For example, if `UserA` exists in both Active Directory and esusers, and the Active Directory realm is checked first and
esusers is checked second, an attempt to authenticate as `UserA` in the esusers realm would first attempt to authenticate
against Active Directory and fail, before successfully authenticating against the esusers realm. Because authentication is
verified on each request, the Active Directory realm would be checked - and fail - on each request for `UserA` in the esusers
realm. In this case, while the Shield request completed successfully, the account on Active Directory would have received
several failed login attempts, and that account may become temporarily locked out. Plan the order of your realms accordingly. 

The realm chain can be configured in the `elasticsearch.yml` file. When not explicitly configured, a default chain will be
created that only holds the `esusers` realm in it. When explicitly configured, the created chain will be the exact reflection
of the configuration (e.g. the only realms in the chain will be those configured realms that are enabled)

The following snippet shows an example of realms configuration:


[source,yaml]
----------------------------------------
shield.authc:

	realms:

		esusers:
			type: esusers
			order: 0

		ldap1:
			type: ldap
			order: 1
			enabled: false
			url: 'url_to_ldap1'
			...

		ldap2:
			type: ldap
			order: 2
			url: 'url_to_ldap2'
			...

		ad1:
			type: active_directory
			order: 3
			url: 'url_to_ad'
----------------------------------------

As can be seen above, each realm has a unique name that identifies it. There are three settings that are common to all
realms:

* `type` (required) - Identifies the type of the ream (currently can be `esusers`, `ldap` or `active_directory`). The realm
                      type determines what other settings the realms should be configured with.
* `order` (optional) - Defines the priority/index of the realm within the realm chain. This will determine when the realm
                       will be consulted during authentication.
* `enabled` (optional) - When set to `false` the realm will be disabled and will not be added to the realm chain. This is
                         useful for debugging purposes, where one can remove a realm from the chain without deleting and
                         losing its configuration.

The realm types can roughly be categorized to two categories:

* `internal` - Internal realm types are realms that are internal to elasticsearch and don't require any communication with
               external parties - they are fully managed by shield. There can only be a maximum of one configured realm
               per internal realm type. (Currently, only one internal realm type exists - `esusers`).

* `external` - External realm types are realms that require interaction with parties/components external to elasticsearch,
               typically, with enterprise level identity management systems. Unlike the `internal` realms, there can be
               as many `external` realms as one would like - each with a unique name and different settings. (Currently
               the only `external` realm types that exist are `ldap` and `active_directory`).

[[anonymous-access]]
[float]
=== Anonymous Access added[1.1.0]

The authentication process can be split into two phases - token extraction and user authentication. During the first
phase (token extraction phase), the configured realms are requested to try and extract/resolve an authentication token
from the incoming request. The first realm that finds an authentication token in the request "wins", meaning, the found
authentication token will be used for authentication (moving to the second phase - user authentication - where each realm
that support this authentication token type will try to authenticate the user).

In the event where no authentication token was resolved by any of the active realms, the incoming request is considered
to be anonymous.

By default, anonymous requests are rejected and an authentication error is returned (status code `401`). It is possible
to change this behaviour and instruct Shield to associate an default/anonymous user with the anonymous request. This can
be done by configuring the following settings in the `elasticsearch.yml` file:

[source,yaml]
----------------------------------------
shield.authc:
  anonymous:
    username: anonymous_user <1>
    roles: role1, role2 <2>
    authz_exception: true <3>
----------------------------------------
<1> The username/principal of the anonymous user. This setting is optional and will be set to `_es_anonymous_user` by default
	when not configured.
<2> The roles that will be associated with the anonymous user. This setting is mandatory - without it, anonymous access
	will be disabled (i.e. anonymous requests will be rejected and return an authentication error)
<3> When `true`, a HTTP 403 response will be returned when the anonymous user does not have the appropriate permissions
    for the requested action. The web browser will not be prompt the user to provide credentials to access the requested
    resource. When set to `false`, a HTTP 401 will be returned allowing for credentials to be provided for a user with
    the appropriate permissions. If you are using anonymous access in combination with HTTP, setting this to `false` may
    be necessary if your client does not support preemptive basic authentication. This setting is optional and will be
    set to `true` by default.

include::realms/01-esusers.asciidoc[]

include::realms/02-ldap.asciidoc[]

include::realms/03-active-directory.asciidoc[]

include::realms/04-pki.asciidoc[]
