This change adds documentation for the SAML APIs in Elasticsearch and adds simple instructions on how these APIs can be used to authenticate a user with SAML by a custom web application other than Kibana. Resolves: #40352
This commit is contained in:
parent
c62fe8c344
commit
33705c4b95
|
@ -29,6 +29,7 @@ project.copyRestSpec.from(xpackResources) {
|
|||
|
||||
testClusters.integTest {
|
||||
extraConfigFile 'op-jwks.json', xpackProject('test:idp-fixture').file("oidc/op-jwks.json")
|
||||
extraConfigFile 'idp-docs-metadata.xml', xpackProject('test:idp-fixture').file("idp/shibboleth-idp/metadata/idp-docs-metadata.xml")
|
||||
extraConfigFile 'testClient.crt', xpackProject('plugin:security').file("src/test/resources/org/elasticsearch/xpack/security/action/pki_delegation/testClient.crt")
|
||||
setting 'xpack.security.enabled', 'true'
|
||||
setting 'xpack.security.authc.api_key.enabled', 'true'
|
||||
|
@ -52,6 +53,13 @@ testClusters.integTest {
|
|||
setting 'xpack.security.authc.realms.pki.pki1.order', '3'
|
||||
setting 'xpack.security.authc.realms.pki.pki1.certificate_authorities', '[ "testClient.crt" ]'
|
||||
setting 'xpack.security.authc.realms.pki.pki1.delegation.enabled', 'true'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.order', '4'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.idp.entity_id', 'https://my-idp.org'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.idp.metadata.path', 'idp-docs-metadata.xml'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.sp.entity_id', 'https://kibana.org'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.sp.acs', 'https://kibana.org/api/security/v1/saml'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.attributes.principal', 'uid'
|
||||
setting 'xpack.security.authc.realms.saml.saml1.attributes.name', 'urn:oid:2.5.4.3'
|
||||
user username: 'test_admin'
|
||||
}
|
||||
|
||||
|
|
|
@ -83,12 +83,24 @@ native realm:
|
|||
=== OpenID Connect
|
||||
|
||||
You can use the following APIs to authenticate users against an OpenID Connect
|
||||
authentication realm
|
||||
authentication realm when using a custom web application other than Kibana
|
||||
|
||||
* <<security-api-oidc-prepare-authentication, Prepare an authentication request>>
|
||||
* <<security-api-oidc-authenticate, Submit an authentication response>>
|
||||
* <<security-api-oidc-logout, Logout an authenticated user>>
|
||||
|
||||
[float]
|
||||
[[security-saml-apis]]
|
||||
=== SAML
|
||||
|
||||
You can use the following APIs to authenticate users against a SAML authentication
|
||||
realm when using a custom web application other than Kibana
|
||||
|
||||
* <<security-api-saml-prepare-authentication, Prepare an authentication request>>
|
||||
* <<security-api-saml-authenticate, Submit an authentication response>>
|
||||
* <<security-api-saml-logout, Logout an authenticated user>>
|
||||
* <<security-api-saml-invalidate, Submit a logout request from the IdP>>
|
||||
|
||||
|
||||
include::security/authenticate.asciidoc[]
|
||||
include::security/change-password.asciidoc[]
|
||||
|
@ -119,4 +131,8 @@ include::security/invalidate-tokens.asciidoc[]
|
|||
include::security/oidc-prepare-authentication-api.asciidoc[]
|
||||
include::security/oidc-authenticate-api.asciidoc[]
|
||||
include::security/oidc-logout-api.asciidoc[]
|
||||
include::security/saml-prepare-authentication-api.asciidoc[]
|
||||
include::security/saml-authenticate-api.asciidoc[]
|
||||
include::security/saml-logout-api.asciidoc[]
|
||||
include::security/saml-invalidate-api.asciidoc[]
|
||||
include::security/ssl.asciidoc[]
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
[role="xpack"]
|
||||
[[security-api-saml-authenticate]]
|
||||
=== SAML authenticate API
|
||||
|
||||
Submits a SAML `Response` message to {es} for consumption.
|
||||
|
||||
NOTE: This API is intended for use by custom web applications other than {kib}.
|
||||
If you are using {kib}, see the <<saml-guide>>.
|
||||
|
||||
[[security-api-saml-authenticate-request]]
|
||||
==== {api-request-title}
|
||||
|
||||
`POST /_security/saml/authenticate`
|
||||
|
||||
[[security-api-saml-authenticate-desc]]
|
||||
==== {api-description-title}
|
||||
|
||||
The SAML message that is submitted can be:
|
||||
|
||||
* a response to a SAML authentication request that was previously created using the
|
||||
<<security-api-saml-prepare-authentication, SAML prepare authentication API>>.
|
||||
* an unsolicited SAML message in the case of an IdP-initiated single sign-on (SSO) flow.
|
||||
|
||||
In either cases, the SAML message needs to be a base64 encoded XML document with a root
|
||||
element of `<Response>`
|
||||
|
||||
After successful validation, {es} responds with an
|
||||
{es} internal access token and refresh token that can be subsequently used for authentication.
|
||||
This API endpoint essentially exchanges SAML responses that
|
||||
indicate successful authentication in the IdP for {es} access and refresh tokens,
|
||||
which can be used for authentication against {es}.
|
||||
|
||||
{es} exposes all the necessary SAML related functionality via the SAML APIs.
|
||||
These APIs are used internally by {kib} in order to provide SAML based
|
||||
authentication, but can also be used by other, custom web applications or other
|
||||
clients. See also
|
||||
<<security-api-saml-prepare-authentication,SAML prepare authentication API>>,
|
||||
<<security-api-saml-invalidate,SAML invalidate API>> and
|
||||
<<security-api-saml-logout,SAML logout API>>.
|
||||
|
||||
|
||||
[[security-api-saml-authenticate-request-body]]
|
||||
==== {api-request-body-title}
|
||||
|
||||
`content`::
|
||||
(Required, string) The SAML response as it was sent by the user's browser, usually a
|
||||
Base64 encoded XML document.
|
||||
|
||||
`ids`::
|
||||
(Required, array) A json array with all the valid SAML Request Ids that the caller of
|
||||
the API has for the current user.
|
||||
|
||||
[[security-api-saml-authenticate-response-body]]
|
||||
==== {api-response-body-title}
|
||||
|
||||
`access_token`::
|
||||
(string) The access token that was generated by {es}.
|
||||
`username`::
|
||||
(string) The authenticated user's name.
|
||||
`expires_in`::
|
||||
(integer) The amount of time (in seconds) left until the token expires.
|
||||
`refresh_token`::
|
||||
(string) The refresh token that was generated by {es}.
|
||||
|
||||
[[security-api-saml-authenticate-example]]
|
||||
==== {api-examples-title}
|
||||
|
||||
The following example exchanges a SAML Response indicating a successful
|
||||
authentication at the SAML IdP for an {es} access token and refresh token to be
|
||||
used in subsequent requests:
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/authenticate
|
||||
{
|
||||
"content" : "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMD.....",
|
||||
"ids" : ["4fee3b046395c4e751011e97f8900b5273d56685"]
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TEST[skip:handled in IT]
|
||||
|
||||
The API returns the following response:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"access_token" : "46ToAxZVaXVVZTVKOVF5YU04ZFJVUDVSZlV3",
|
||||
"username" : "Bearer",
|
||||
"expires_in" : 1200,
|
||||
"refresh_token": "mJdXLtmvTUSpoLwMvdBt_w"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// NOTCONSOLE
|
|
@ -0,0 +1,91 @@
|
|||
[role="xpack"]
|
||||
[[security-api-saml-invalidate]]
|
||||
=== SAML invalidate API
|
||||
|
||||
Submits a SAML LogoutRequest message to {es} for consumption.
|
||||
|
||||
NOTE: This API is intended for use by custom web applications other than {kib}.
|
||||
If you are using {kib}, see the <<saml-guide>>.
|
||||
|
||||
[[security-api-saml-invalidate-request]]
|
||||
==== {api-request-title}
|
||||
|
||||
`POST /_security/saml/invalidate`
|
||||
|
||||
[[security-api-saml-invalidate-desc]]
|
||||
==== {api-description-title}
|
||||
|
||||
The logout request comes from the SAML IdP during an IdP initiated Single Logout.
|
||||
The custom web application can use this API to have {es} process the `LogoutRequest`.
|
||||
After successful validation of the request, {es} invalidates the access token
|
||||
and refresh token that corresponds to that specific SAML principal and provides
|
||||
a URL that contains a SAML LogoutResponse message, so that the user can be
|
||||
redirected back to their IdP.
|
||||
|
||||
{es} exposes all the necessary SAML related functionality via the SAML APIs.
|
||||
These APIs are used internally by {kib} in order to provide SAML based
|
||||
authentication, but can also be used by other custom web applications or other
|
||||
clients. See also <<security-api-saml-authenticate,SAML authenticate API>>,
|
||||
<<security-api-saml-prepare-authentication,SAML prepare authentication API>>,
|
||||
and <<security-api-saml-logout,SAML logout API>>.
|
||||
|
||||
[[security-api-saml-invalidate-request-body]]
|
||||
==== {api-request-body-title}
|
||||
|
||||
`acs`::
|
||||
(Optional, string) The Assertion Consumer Service URL that matches the one of the SAML
|
||||
realm in {es} that should be used. You must specify either this parameter or the `realm` parameter.
|
||||
|
||||
`queryString`::
|
||||
(Required, string) The query part of the URL that the user was redirected to by the SAML
|
||||
IdP to initiate the Single Logout. This query should include a single
|
||||
parameter named `SAMLRequest` that contains a SAML logout request that is
|
||||
deflated and Base64 encoded. If the SAML IdP has signed the logout request,
|
||||
the URL should include two extra parameters named `SigAlg` and `Signature`
|
||||
that contain the algorithm used for the signature and the signature value itself.
|
||||
In order for {es} to be able to verify the IdP's signature, the value of the queryString field must be an exact match to the string provided by the browser.
|
||||
The client application must not attempt to parse or process the string in any way.
|
||||
|
||||
`realm`::
|
||||
(Optional, string) The name of the SAML realm in {es} the configuration. You must specify
|
||||
either this parameter or the `acs` parameter.
|
||||
|
||||
[[security-api-saml-invalidate-response-body]]
|
||||
==== {api-response-body-title}
|
||||
|
||||
`invalidated`::
|
||||
(integer) The number of tokens that were invalidated as part of this logout.
|
||||
|
||||
`realm`::
|
||||
(string) The realm name of the SAML realm in {es} that authenticated the user.
|
||||
|
||||
`redirect`::
|
||||
(string) A SAML logout response as a parameter so that the user can be
|
||||
redirected back to the SAML IdP.
|
||||
|
||||
|
||||
[[security-api-saml-invalidate-example]]
|
||||
==== {api-examples-title}
|
||||
|
||||
The following example invalidates all the tokens for realm `saml1` pertaining to
|
||||
the user that is identified in the SAML Logout Request:
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/invalidate
|
||||
{
|
||||
"queryString" : "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"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TEST[skip:handled in IT]
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"redirect" : "https://my-idp.org/logout/SAMLResponse=....",
|
||||
"invalidated" : 2,
|
||||
"realm" : "saml1"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// NOTCONSOLE
|
|
@ -0,0 +1,79 @@
|
|||
[role="xpack"]
|
||||
[[security-api-saml-logout]]
|
||||
=== SAML logout API
|
||||
|
||||
Submits a request to invalidate an access token and refresh token.
|
||||
|
||||
NOTE: This API is intended for use by custom web applications other than {kib}.
|
||||
If you are using {kib}, see the <<saml-guide>>.
|
||||
|
||||
[[security-api-saml-logout-request]]
|
||||
==== {api-request-title}
|
||||
|
||||
`POST /_security/saml/logout`
|
||||
|
||||
[[security-api-saml-logout-desc]]
|
||||
==== {api-description-title}
|
||||
|
||||
This API invalidates the tokens that were generated for a user by the
|
||||
<<security-api-saml-authenticate,SAML authenticate API>>.
|
||||
|
||||
If the SAML realm in {es} is configured accordingly and the SAML IdP supports
|
||||
this, the {es} response contains a URL to redirect the user to the IdP
|
||||
that contains a SAML logout request (starting an SP-initiated SAML Single Logout).
|
||||
|
||||
{es} exposes all the necessary SAML related functionality via the SAML APIs.
|
||||
These APIs are used internally by {kib} in order to provide SAML based
|
||||
authentication, but can also be used by other custom web applications or other
|
||||
clients. See also <<security-api-saml-authenticate,SAML authenticate API>>,
|
||||
<<security-api-saml-prepare-authentication,SAML prepare authentication API>>,
|
||||
and <<security-api-saml-invalidate,SAML invalidate API>>.
|
||||
|
||||
[[security-api-saml-logout-request-body]]
|
||||
==== {api-request-body-title}
|
||||
|
||||
`token`::
|
||||
(Required, string) The access token that was returned as a response to calling the
|
||||
<<security-api-saml-authenticate,SAML authenticate API>>. Alternatively, the most
|
||||
recent token that was received after refreshing the original one by using a
|
||||
`refresh_token`.
|
||||
|
||||
`refresh_token`::
|
||||
(Optional, string) The refresh token that was returned as a response to calling the
|
||||
<<security-api-saml-authenticate,SAML authenticate API>>. Alternatively, the
|
||||
most recent refresh token that was received after refreshing the original access token.
|
||||
|
||||
[[security-api-saml-logout-response-body]]
|
||||
==== {api-response-body-title}
|
||||
|
||||
`redirect`::
|
||||
(string) A URL that contains a SAML logout request as a parameter. The user
|
||||
can use this URL to be redirected back to the SAML IdP and to initiate Single
|
||||
Logout.
|
||||
|
||||
[[security-api-saml-logout-example]]
|
||||
==== {api-examples-title}
|
||||
|
||||
The following example invalidates the pair of tokens that were generated by
|
||||
calling the <<security-api-saml-authenticate,SAML authenticate API>>
|
||||
with a successful SAML response:
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/logout
|
||||
{
|
||||
"token" : "46ToAxZVaXVVZTVKOVF5YU04ZFJVUDVSZlV3",
|
||||
"refresh_token" : "mJdXLtmvTUSpoLwMvdBt_w"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TEST[skip:can't test this without a valid SAML Response]
|
||||
|
||||
The API returns the following response:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"redirect" : "https://my-idp.org/logout/SAMLRequest=...."
|
||||
}
|
||||
--------------------------------------------------
|
||||
// NOTCONSOLE
|
|
@ -0,0 +1,98 @@
|
|||
[role="xpack"]
|
||||
[[security-api-saml-prepare-authentication]]
|
||||
=== SAML prepare authentication API
|
||||
|
||||
Creates a SAML authentication request (`<AuthnRequest>`) as a URL string, based on the configuration of the respective SAML realm in {es}.
|
||||
|
||||
NOTE: This API is intended for use by custom web applications other than {kib}.
|
||||
If you are using {kib}, see the <<saml-guide>>.
|
||||
|
||||
[[security-api-saml-prepare-authentication-request]]
|
||||
==== {api-request-title}
|
||||
|
||||
`POST /_security/saml/prepare`
|
||||
|
||||
[[security-api-saml-prepare-authentication-desc]]
|
||||
==== {api-description-title}
|
||||
|
||||
This API returns a URL pointing to the SAML Identity
|
||||
Provider. You can use the URL to redirect the browser of the user in order to
|
||||
continue the authentication process. The URL includes a single parameter named `SAMLRequest`,
|
||||
which contains a SAML Authentication request that is deflated and
|
||||
Base64 encoded. If the configuration dictates that SAML authentication requests
|
||||
should be signed, the URL has two extra parameters named `SigAlg` and
|
||||
`Signature`. These parameters contain the algorithm used for the signature and
|
||||
the signature value itself.
|
||||
It also returns a random string that uniquely identifies this SAML Authentication request. The
|
||||
caller of this API needs to store this identifier as it needs to used in a following step of
|
||||
the authentication process (see <<security-api-saml-authenticate,SAML authenticate API>>).
|
||||
|
||||
{es} exposes all the necessary SAML related functionality via the SAML APIs.
|
||||
These APIs are used internally by {kib} in order to provide SAML based
|
||||
authentication, but can also be used by other custom web applications or other
|
||||
clients. See also <<security-api-saml-authenticate,SAML authenticate API>>,
|
||||
<<security-api-saml-invalidate,SAML invalidate API>>, and
|
||||
<<security-api-saml-logout,SAML logout API>>.
|
||||
|
||||
[[security-api-saml-prepare-authentication-request-body]]
|
||||
==== {api-request-body-title}
|
||||
|
||||
`acs`::
|
||||
(Optional, string) The Assertion Consumer Service URL that matches the one of the SAML
|
||||
realms in {es}. The realm is used to generate the authentication request.
|
||||
You must specify either this parameter or the `realm` parameter.
|
||||
|
||||
`realm`::
|
||||
(Optional, string) The name of the SAML realm in {es} for which the configuration is
|
||||
used to generate the authentication request. You must specify either this parameter or the `acs`
|
||||
parameter.
|
||||
|
||||
[[security-api-saml-prepare-authentication-response-body]]
|
||||
==== {api-response-body-title}
|
||||
|
||||
`id`::
|
||||
(string) A unique identifier for the SAML Request to be stored by the caller
|
||||
of the API.
|
||||
|
||||
`realm`::
|
||||
(string) The name of the {es} realm that was used to construct the
|
||||
authentication request.
|
||||
|
||||
`redirect`::
|
||||
(string) The URL to redirect the user to.
|
||||
|
||||
[[security-api-saml-prepare-authentication-example]]
|
||||
==== {api-examples-title}
|
||||
|
||||
The following example generates a SAML authentication request for the SAML realm with name `saml1`
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/prepare
|
||||
{
|
||||
"realm" : "saml1"
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
The following example generates a SAML authentication request for the SAML realm with an Assertion
|
||||
Consuming Service URL matching `https://kibana.org/api/security/v1/saml
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/prepare
|
||||
{
|
||||
"acs" : "https://kibana.org/api/security/v1/saml"
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
This API returns the following response:
|
||||
|
||||
[source,js]
|
||||
-------------------------------------------------
|
||||
{
|
||||
"redirect": "https://my-idp.org/login?SAMLRequest=fVJdc6IwFP0rmbwDgUKLGbFDtc462%2B06FX3Yl50rBJsKCZsbrPbXL6J22hdfk%2FNx7zl3eL%2BvK7ITBqVWCfVdRolQuS6k2iR0mU2dmN6Phgh1FTQ8be2rehH%2FWoGWdESF%2FPST0NYorgElcgW1QG5zvkh%2FPfHAZbwx2upcV5SkiMLYzmqsFba1MAthdjIXy5enhL5a23DPOyo6W7kGBa7cwhZ2gO7G8OiW%2BR400kORt0bag7fzezAlk24eqcD2OxxlsNN5O3MdsW9c6CZnbq7rntF4d3s0D7BaHTZhIWN52P%2BcjiuGRbDU6cdj%2BEjJbJLQv4N4ADdhxBiEZbQuWclY4Q8iABbCXczCdSiKMAC%2FgyO2YqbQgrIJDZg%2FcFjsMD%2Fzb3gUcBa5sR%2F9oWR%2BzuJBqlPG14Jbn0DIf2TZ3Jn%2FXmSUrC5ddQB6bob37uZrJdeF4dIDHV3iuhb70Ptq83kOz53ubDLXlcwPJK0q%2FT42AqxIaAkVCkqm2tRgr49yfJGFU%2FZQ3hy3QyuUpd7obPv97kb%2FAQ%3D%3D"}",
|
||||
"realm": "saml1",
|
||||
"id": "_989a34500a4f5bf0f00d195aa04a7804b4ed42a1"
|
||||
}
|
||||
-------------------------------------------------
|
||||
// NOTCONSOLE
|
|
@ -659,8 +659,8 @@ POST /_security/oidc/authenticate
|
|||
// TEST[catch:unauthorized]
|
||||
+
|
||||
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 and a refresh token that can be later used to refresh the given
|
||||
access token as described in {ref}/security-api-get-token.html[get token API].
|
||||
as a `Bearer` token for subsequent requests and a refresh token that can be later used to refresh the given
|
||||
access token as described in {ref}/security-api-get-token.html[get token API].
|
||||
. At some point, if necessary, the custom web application can log the user out by using the
|
||||
{ref}/security-api-oidc-logout.html[OIDC Logout API] passing the access token and refresh token as parameters. For example:
|
||||
+
|
||||
|
|
|
@ -847,3 +847,167 @@ A conscious effort has been made to mask this complexity with sane defaults and
|
|||
documentation above but in case you encounter issues while configuring a SAML realm, you can
|
||||
look through our <<trb-security-saml,SAML troubleshooting documentation>> that has
|
||||
suggestions and resolutions for common issues.
|
||||
|
||||
[[saml-no-kibana]]
|
||||
=== SAML without {kib}
|
||||
|
||||
The SAML realm in {es} is designed to allow users to authenticate to {kib} and as
|
||||
such, most of the parts of the guide above make the assumption that {kib} is used.
|
||||
This section describes how a custom web application could use the relevant SAML
|
||||
REST APIs in order to authenticate the users to {es} with SAML.
|
||||
|
||||
NOTE: 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
|
||||
{es} and in principle exchange a SAML or OpenID Connect Authentication response for
|
||||
an {es} access token and a refresh token. The access token is used as credentials
|
||||
for subsequent calls to {es}. The refresh token enables the user to get new {es}
|
||||
access tokens after the current one expires.
|
||||
|
||||
[[saml-no-kibana-realm]]]
|
||||
==== SAML realm
|
||||
|
||||
You must create a SAML realm and configure it accordingly
|
||||
in {es}. See <<saml-guide-authentication>>
|
||||
|
||||
[[saml-no-kibana-user]]
|
||||
==== 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.
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/role/saml-service-role
|
||||
{
|
||||
"cluster" : ["manage_saml", "manage_token"]
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/user/saml-service-user
|
||||
{
|
||||
"password" : "<somePasswordHere>",
|
||||
"roles" : ["saml-service-role"]
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
[[saml-no-kibana-sp-init-sso]]
|
||||
==== 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 {es}:
|
||||
|
||||
. Make an HTTP POST request to `_security/saml/prepare`, authenticating as
|
||||
the `saml-service-user` user. Use either the name of the SAML realm in the {es} configuration or the value for
|
||||
the Assertion Consumer Service URL in the request body.
|
||||
See the <<security-api-saml-prepare-authentication,SAML prepare authentication API>> for more details.
|
||||
+
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/prepare
|
||||
{
|
||||
"realm" : "saml1"
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
. Handle the response from `/_security/saml/prepare`. The response from {es} will contain 3 parameters:
|
||||
`redirect`, `realm' and `id`. The custom web application would need to store the value for `id`
|
||||
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 the
|
||||
`redirect` parameter. The `id` 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 the `saml-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 for `id` that it had saved in the user's session previously.
|
||||
+
|
||||
See <<security-api-saml-authenticate,SAML authenticate API>> for more details.
|
||||
+
|
||||
[source,console]
|
||||
-----------------------------------------------------------------------
|
||||
POST /_security/saml/authenticate
|
||||
{
|
||||
"content" : "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMD.....",
|
||||
"ids" : ["4fee3b046395c4e751011e97f8900b5273d56685"]
|
||||
}
|
||||
-----------------------------------------------------------------------
|
||||
// TEST[skip:handled in IT]
|
||||
+
|
||||
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 <<security-api-get-token,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 a `Bearer` token
|
||||
and the SAML attribute values will be contained in the response as part of the <<saml-user-metadata>>.
|
||||
|
||||
[[saml-no-kibana-idp-init-sso]]
|
||||
==== Handling the IdP-initiated authentication flow
|
||||
|
||||
{es} 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 <<saml-no-kibana-sp-init-sso, 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:
|
||||
|
||||
|
||||
[source,console]
|
||||
-----------------------------------------------------------------------
|
||||
POST /_security/saml/authenticate
|
||||
{
|
||||
"content" : "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMD.....",
|
||||
"ids" : []
|
||||
}
|
||||
-----------------------------------------------------------------------
|
||||
// TEST[skip:handled in IT]
|
||||
|
||||
[[saml-no-kibana-slo]]
|
||||
==== Handling the logout flow
|
||||
. At some point, if necessary, the custom web application can log the user out by using the
|
||||
<<security-api-saml-logout,SAML logout API>> and passing the access token and refresh token as parameters. For example:
|
||||
+
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_security/saml/logout
|
||||
{
|
||||
"token" : "46ToAxZVaXVVZTVKOVF5YU04ZFJVUDVSZlV3",
|
||||
"refresh_token": "mJdXLtmvTUSpoLwMvdBt_w"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TEST[skip:handled in IT]
|
||||
+
|
||||
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 {es}
|
||||
using the <<security-api-saml-invalidate,SAML invalidate API>>
|
||||
+
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
POST /_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"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TEST[skip:handled in IT]
|
||||
+
|
||||
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.
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:req-attr="urn:oasis:names:tc:SAML:protocol:ext:req-attr" entityID="https://my-idp.org">
|
||||
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<KeyDescriptor use="signing">
|
||||
<ds:KeyInfo>
|
||||
<ds:X509Data>
|
||||
<ds:X509Certificate>
|
||||
MIIEUjCCArqgAwIBAgIVALjpmEEY4k5+2/JXwk5y+MoDnWiAMA0GCSqGSIb3DQEB
|
||||
CwUAMCgxJjAkBgNVBAMMHXRlc3Quc2hpYmJvbGV0aC5lbGFzdGljLmxvY2FsMB4X
|
||||
DTE5MDMwODEzMTg1OVoXDTM5MDMwODEzMTg1OVowKDEmMCQGA1UEAwwddGVzdC5z
|
||||
aGliYm9sZXRoLmVsYXN0aWMubG9jYWwwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
|
||||
ggGKAoIBgQC98CVCuq4MBwBGia77i7tdUMFql+KbY5mY/eENspY59aPZbI6/oMSU
|
||||
v4Uu3iJux8gGlBmkzxoefhuIA93lE+RS3k1iezxtS0fQW8drYCtJRT9j8xuEdzo9
|
||||
hHV3wa4lhnC8Mfn6K79jzj0Y6PkDCSS3wn80YYAQpI0sV6baxGuRByL7BMjHITFw
|
||||
EbFYsph6zQ/3SZu1OWocVdgZkF+n3zraUDuj87M+Tn6RRhWF0Jq/vFAUNCTWr7Iw
|
||||
GTUib9LWx3v5IqXttu9NBMSd5Q5mIoPWW+/RA3mpcsN51rVRa2od6HABpiEv7I7B
|
||||
yEtBVNPkYfOPF2TIxefeyIl3UCD5sF/2nDAZfe/ENnJFQwqnPAXwXrlPlLCoWsOl
|
||||
OOHfyE7tbORkVXNuWYq9TcTNLEIuB081Utxsoa+iiWGyn0/uYDg2NGxJ2V2/PISf
|
||||
LhUilCJSmNbMUFirVSUJD8mntn8VRidn1/Wx7RCphPGmMmJtAN080/+zCOJVE4/G
|
||||
6JnRMFpNZO0CAwEAAaNzMHEwHQYDVR0OBBYEFH9wTxThSEj7nswt0sIjbpw86itt
|
||||
MFAGA1UdEQRJMEeCHXRlc3Quc2hpYmJvbGV0aC5lbGFzdGljLmxvY2FshiZodHRw
|
||||
czovL3Rlc3Quc2hpYmJvbGV0aC5lbGFzdGljLmxvY2FsLzANBgkqhkiG9w0BAQsF
|
||||
AAOCAYEApBpPTKvKUwcZ8Tfm3TZPINmSXI05OWU1Xu8gdFB0EoUDFE9/uHTJgfmS
|
||||
5ZjUT8YGhHH883XKNq9JhmyCb5V5ZSjONzMGplcsTAkk0guU0DqKvabyVsQuyne6
|
||||
nCkbAr/srtJFutiFJDGmfAmhTSFTVmpI4stpyC+y5Y0PhcUQa6Ytz8wGTMJvftv5
|
||||
2S5zhX9IDaWo4C97WWnSXaFepi5n1i4wlCj5HgDkEhoeEt5byJMxzDdN9whEI5Ju
|
||||
VPMUcRcJNajnSKA1SVAznUpJbHSu0WAfM/MQ9ucX3o3A5J/bA9xlknsEWtugtvRK
|
||||
KCwuibrOddrv/cQQbpPjDhWk/VF7tOA1kuSHHdYICB+WjWU463bv0rLm6QXqkDU4
|
||||
f3XuG2zJTmVQEzBdmv9ATlqQ+sADV216Vyy5I/delW0WnmePGTuxBj+Xm7VrbYNi
|
||||
WOveqK14343Bpbo8H/V2UvTPGF+oICnmw0fgG7SChtcDY9won6mRVCcy+01TeOua
|
||||
TSYuiKRN
|
||||
</ds:X509Certificate>
|
||||
</ds:X509Data>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<KeyDescriptor use="signing">
|
||||
<ds:KeyInfo>
|
||||
<ds:X509Data>
|
||||
<ds:X509Certificate>
|
||||
MIIEUjCCArqgAwIBAgIVAMo/bS4nTf4TlWhmWu7auvJhceTMMA0GCSqGSIb3DQEB
|
||||
CwUAMCgxJjAkBgNVBAMMHXRlc3Quc2hpYmJvbGV0aC5lbGFzdGljLmxvY2FsMB4X
|
||||
DTE5MDMwODEzMTg1OVoXDTM5MDMwODEzMTg1OVowKDEmMCQGA1UEAwwddGVzdC5z
|
||||
aGliYm9sZXRoLmVsYXN0aWMubG9jYWwwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
|
||||
ggGKAoIBgQCGXWD/YD5VD52S6vmy1iRzYI7ZxAsyiDSOP3qQgRtcHssgNluTae6r
|
||||
GIoj5m3tfQayHmh7ctI3zLhwReD9GlLZuV2JxaIfn/4e1N2dsLFvgYMmao9g41DE
|
||||
/RG2Zjl/K9Ux3v0xUx5uoK0p68GR3ykYjf/Ea0AIJCx+SfRt6uOQ0nlAC19/gffJ
|
||||
G1pzcbWxZMxx5jJ8bULtxbAgC7tW21V9kq6fBKwTpJS7XVC4xwou8Vi5NnoPwjbv
|
||||
f9Agg1TuLI+Loa0+gK3exh0jGlHfvBZMobX8fZI7yDkt60hFe5g97R2yJuVekHR3
|
||||
VUyAG1xYWcS2l6tJ7XVQKRrwlwUumG0bsnBfa918p6V7pOsS5quKTCQpWkxpXO37
|
||||
BSbd3TrlpSde0ncFHg3bAxIPtlxbJe87CA4y9JuyrjqCqw8WC5clNCvlGBx5aKgu
|
||||
986/TWK8neeJZTQRpo+Nwf+Q8tuNb21tYA7B04h2MMumdRcVJ5IXDuVuVZJecNZp
|
||||
LZODW3bHiGECAwEAAaNzMHEwHQYDVR0OBBYEFGtVRTYHCuBUetx2T2KF8MkvAcwQ
|
||||
MFAGA1UdEQRJMEeCHXRlc3Quc2hpYmJvbGV0aC5lbGFzdGljLmxvY2FshiZodHRw
|
||||
czovL3Rlc3Quc2hpYmJvbGV0aC5lbGFzdGljLmxvY2FsLzANBgkqhkiG9w0BAQsF
|
||||
AAOCAYEAe5fL8bstZsj6p1lZ3fIMjeRcz60BmDyIobQFTQu9PkRa3hcLZdCRtuNL
|
||||
BfQbNr4Kymo8GP9c/RkmjIxl32cyCrt7kLWLurUptfYO8IgXpvnQ8EfdSO9PBDag
|
||||
x5WVg8SHVJ+IeL2k+D/EnyQUisQPau0JmJCNQsAuzGrg8FmHa7IBDvWtAmO4BRRd
|
||||
pZgyC/mfEwF8mbGoRJt7oHs30a+5RVHUhRDLhQD0+L3efgEvq+9lsDKIQHzG2ITg
|
||||
Z5qqLkYP6nlNlMHU+xS9by4DT4u9IOOsQJ2DS/PNrYFRLNUwDKkdBFrhy3uM0UYl
|
||||
e8Gvcow0paET4e1i50Urk7Yrnadcr7B9nNqHCrqW6QyuZmurhxyhAIiwYlc+fCVy
|
||||
BUM9IlZ9yuQNRmTLr9irWbajfKSTtfzJDwid9ZKmKCDzDMci3oobVc8xTOGckoyB
|
||||
QEyPGpCHu0JACjMUt/qqt/qD0xJTIibRrwPEOBKrxrCFwMfzdKnlmVUGNhI4cA88
|
||||
TvpYlz3p
|
||||
</ds:X509Certificate>
|
||||
</ds:X509Data>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<KeyDescriptor use="encryption">
|
||||
<ds:KeyInfo>
|
||||
<ds:X509Data>
|
||||
<ds:X509Certificate>
|
||||
MIIEUTCCArmgAwIBAgIUcpV0WDMWve6/1FPqzjYJnMLDLRIwDQYJKoZIhvcNAQEL
|
||||
BQAwKDEmMCQGA1UEAwwddGVzdC5zaGliYm9sZXRoLmVsYXN0aWMubG9jYWwwHhcN
|
||||
MTkwMzA4MTMxODU5WhcNMzkwMzA4MTMxODU5WjAoMSYwJAYDVQQDDB10ZXN0LnNo
|
||||
aWJib2xldGguZWxhc3RpYy5sb2NhbDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCC
|
||||
AYoCggGBAI4haOiDT0q1eBqwKWbOUfxTVQ2d3nC4wpPekB8YixcePBHu1GEKnCmO
|
||||
E1/EHyhc5EA0p+IV4GRfwEC4bwWOFt5xY2XJREeXg21G1pQ0R2aHIb9cmJWuHHBt
|
||||
4pIaEiOw1se4zfiTNgcO2WOc6ixmx/cJYjd+FvMPP3Y96JFycVt7f4DTUZ/IGUTO
|
||||
jOjwRet9vpBHBzIIN+MEnarwd3mPt3FLhsMU09Q/C3Jfw9x+HcSrCQn7d/3ucvZL
|
||||
iRdYfGxr6YVapwij5eRkVDx6pRi4jTWgNy7BGieWJLElDoPTapmPZxhTIkxnv9/A
|
||||
HqZmOc2hErU/aPKe/H5doC9Sfj9jEhXURVYeK7Rsmq8IVW6WnVxODjO62/mS58Uu
|
||||
slkLiNBd0GDx+PRm7YG1k3khJFihtL1xfKIE8PUEqemYIvoHY3/xTujplUDTdHlC
|
||||
VRaf5/QhT+vgcn7JEXnWtgW1SzSg//lmN1htfOlPb4pXa/Y/Gg2JrsMXXgu098X8
|
||||
u++qOorK2QIDAQABo3MwcTAdBgNVHQ4EFgQUUxIigNlOHt4GZvE4XwmwPq0H2xsw
|
||||
UAYDVR0RBEkwR4IddGVzdC5zaGliYm9sZXRoLmVsYXN0aWMubG9jYWyGJmh0dHBz
|
||||
Oi8vdGVzdC5zaGliYm9sZXRoLmVsYXN0aWMubG9jYWwvMA0GCSqGSIb3DQEBCwUA
|
||||
A4IBgQB3V3QLkSEnix65cZVH1x4ayZfkyYUeXqQEpjsnz4wGPmWXQp/vJ313mWsV
|
||||
dtA6uCEHAhAi1It8QpOw0DkQQ39GYLANkra1skjGqOgqjsqCsEX9haaIVvRrG1YP
|
||||
GA5C6nq88C4KgAYzhfzmOTkDvCLeM/adSV9q8y4juPsrOod81zBjp5GhLfraVUXq
|
||||
6gwMjRqE+eEgX1RGiYDNl3oar4WB6+cCiTsbkJwHsmGc2LviHxlkPRSIPkJtTUAW
|
||||
bTCN38FxQda9Ao6ZavSn2Da/HhQm1yxpOdEfTeBSFS5e6NSqj+X1Mc8y0L5cLUyZ
|
||||
kqQ+q2xhMap2WyDxUm5db9OR5VkrpejR7+f+CYVD7CTt7bqoHQZgaOrGJLje0ZQX
|
||||
cAeMgEFja4nK0TY8+eD+ijEZ3y/LRMsIl5Hetxaw1atgoVKociuhoF5wZSK0OsDQ
|
||||
Qx/AEkhqDaSUfSZvSJlD645k/E20NGiK/a8nsquJ3Tkl8rQDEk8r/IKJVmo+vkuX
|
||||
NgQpDdo=
|
||||
</ds:X509Certificate>
|
||||
</ds:X509Data>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" req-attr:supportsRequestedAttributes="true"
|
||||
Location="https://my-idp.org/login"/>
|
||||
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" req-attr:supportsRequestedAttributes="true"
|
||||
Location="https://my-idp.org/login"/>
|
||||
</IDPSSODescriptor>
|
||||
</EntityDescriptor>
|
Loading…
Reference in New Issue