SAML without Kibana
The SAML realm in Elasticsearch is designed to allow users to authenticate to Kibana and as such, most of the parts of the guide above make the assumption that Kibana is used. This section describes how a custom web application could use the relevant SAML REST APIs in order to authenticate the users to Elasticsearch with SAML.
This section assumes that the reader is familiar with the SAML 2.0 standard and more specifically with the SAML 2.0 Web Browser Single Sign On profile.
Single sign-on realms such as OpenID Connect and SAML make use of the Token Service in Elasticsearch and in principle exchange a SAML or OpenID Connect Authentication response for an Elasticsearch access token and a refresh token. The access token is used as credentials for subsequent calls to Elasticsearch. The refresh token enables the user to get new Elasticsearch access tokens after the current one expires.
SAML realm
You must create a SAML realm and configure it accordingly in Elasticsearch. See Configure Elasticsearch for SAML authentication
Service Account user for accessing the APIs
The realm is designed with the assumption that there needs to be a privileged entity acting as an authentication proxy. In this case, the custom web application is the authentication proxy handling the authentication of end users ( more correctly, “delegating” the authentication to the SAML Identity Provider ). The SAML related APIs require authentication and the necessary authorization level for the authenticated user. For this reason, you must create a Service Account user and assign it a role that gives it the manage_saml
cluster privilege. The use of the manage_token
cluster privilege will be necessary after the authentication takes place, so that the the service account user can maintain access in order refresh access tokens on behalf of the authenticated users or to subsequently log them out.
POST /_security/role/saml-service-role
{
"cluster" : ["manage_saml", "manage_token"]
}
POST /_security/user/saml-service-user
{
"password" : "<somePasswordHere>",
"roles" : ["saml-service-role"]
}
Handling the SP-initiated authentication flow
On a high level, the custom web application would need to perform the following steps in order to authenticate a user with SAML against Elasticsearch:
Make an HTTP POST request to
_security/saml/prepare
, authenticating as thesaml-service-user
user. Use either the name of the SAML realm in the Elasticsearch configuration or the value for the Assertion Consumer Service URL in the request body. See the SAML prepare authentication API for more details.POST /_security/saml/prepare
{
"realm" : "saml1"
}
Handle the response from
/_security/saml/prepare
. The response from Elasticsearch will contain 3 parameters:redirect
,realm
andid
. The custom web application would need to store the value forid
in the user’s session (client side in a cookie or server side if session information is persisted this way). It must also redirect the user’s browser to the URL that was returned in theredirect
parameter. Theid
value should not be disregarded as it is used as a nonce in SAML in order to mitigate against replay attacks.Handle a subsequent response from the SAML IdP. After the user is successfully authenticated with the Identity Provider they will be redirected back to the Assertion Consumer Service URL. This
sp.acs
needs to be defined as a URL which the custom web application handles. When it receives this HTTP POST request, the custom web application must parse it and make an HTTP POST request itself to the_security/saml/authenticate
API. It must authenticate as thesaml-service-user
user and pass the Base64 encoded SAML Response that was sent as the body of the request. It must also pass the value forid
that it had saved in the user’s session previously.See SAML authenticate API for more details.
POST /_security/saml/authenticate
{
"content" : "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMD.....",
"ids" : ["4fee3b046395c4e751011e97f8900b5273d56685"]
}
Elasticsearch will validate this and if all is correct will respond with an access token that can be used as a
Bearer
token for subsequent requests. It also supplies a refresh token that can be later used to refresh the given access token as described in get token API.The response to calling
/_security/saml/authenticate
will contain only the username of the authenticated user. If you need to get the values for the SAML Attributes that were contained in the SAML Response for that user, you can call the Authenticate API/_security/_authenticate/
using the access token as aBearer
token and the SAML attribute values will be contained in the response as part of the User metadata.
Handling the IdP-initiated authentication flow
Elasticsearch can also handle the IdP-initiated Single Sign On flow of the SAML 2 Web Browser SSO profile. In this case the authentication starts with an unsolicited authentication response from the SAML Identity Provider. The difference with the SP initiated SSO is that the web application needs to handle requests to the sp.acs
that will not come as responses to previous redirections. As such, it will not have a session for the user already, and it will not have any stored values for the id
parameter. The request to the _security/saml/authenticate
API will look like the one below in this case:
POST /_security/saml/authenticate
{
"content" : "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMD.....",
"ids" : []
}
Handling the logout flow
At some point, if necessary, the custom web application can log the user out by using the SAML logout API and passing the access token and refresh token as parameters. For example:
POST /_security/saml/logout
{
"token" : "46ToAxZVaXVVZTVKOVF5YU04ZFJVUDVSZlV3",
"refresh_token": "mJdXLtmvTUSpoLwMvdBt_w"
}
If the SAML realm is configured accordingly and the IdP supports it (see SAML logout), this request will trigger a SAML SP-initiated Single Logout. In this case, the response will include a
redirect
parameter indicating where the user needs to be redirected at the IdP in order to complete the logout.Alternatively, the IdP might initiate the Single Logout flow at some point. In order to handle this, the Logout URL (
sp.logout
) needs to be handled by the custom web app. The query part of the URL that the user will be redirected to will contain a SAML Logout request and this query part needs to be relayed to Elasticsearch using the SAML invalidate APIPOST /_security/saml/invalidate
{
"query" : "SAMLRequest=nZFda4MwFIb%2FiuS%2BmviRpqFaClKQdbvo2g12M2KMraCJ9cRR9utnW4Wyi13sMie873MeznJ1aWrnS3VQGR0j4mLkKC1NUeljjA77zYyhVbIE0dR%2By7fmaHq7U%2BdegXWGpAZ%2B%2F4pR32luBFTAtWgUcCv56%2Fp5y30X87Yz1khTIycdgpUW9kY7WdsC9zxoXTvMvWuVV98YyMnSGH2SYE5pwALBIr9QKiwDGpW0oGVUznGeMyJZKFkQ4jBf5HnhUymjIhzCAL3KNFihbYx8TBYzzGaY7EnIyZwHzCWMfiDnbRIftkSjJr%2BFu0e9v%2B0EgOquRiiZjKpiVFp6j50T4WXoyNJ%2FEWC9fdqc1t%2F1%2B2F3aUpjzhPiXpqMz1%2FHSn4A&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=MsAYz2NFdovMG2mXf6TSpu5vlQQyEJAg%2B4KCwBqJTmrb3yGXKUtIgvjqf88eCAK32v3eN8vupjPC8LglYmke1ZnjK0%2FKxzkvSjTVA7mMQe2AQdKbkyC038zzRq%2FYHcjFDE%2Bz0qISwSHZY2NyLePmwU7SexEXnIz37jKC6NMEhus%3D",
"realm" : "saml1"
}
The custom web application will then need to also handle the response, which will include a
redirect
parameter with a URL in the IdP that contains the SAML Logout response. The application should redirect the user there to complete the logout.