Skip to content

Commit

Permalink
Document SAML APIs (elastic#45105)
Browse files Browse the repository at this point in the history
* Document SAML APIs

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: elastic#40352

* typo

* fix links

* fix more links

* [DOCS] Fixes broken link

* Add metadata file with shorter names for docs, fix typos and mute tests

* [DOCS] Reformats the SAML APIs to match API template

* Apply suggestions from code review

Co-Authored-By: Lisa Cawley <[email protected]>

* Address feedback and add small section on IdP-initiated SSO handling

* address feedback

* moar feedback

* Clarifications and addressing feedback

* properly resolve conflicts

* address feedback

* fix doc links

* minor fixes

* Fix reference
  • Loading branch information
jkakavas authored and howardhuanghua committed Oct 14, 2019
1 parent 4737eaf commit 8ea92f1
Show file tree
Hide file tree
Showing 9 changed files with 657 additions and 3 deletions.
8 changes: 8 additions & 0 deletions x-pack/docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'
}

Expand Down
18 changes: 17 additions & 1 deletion x-pack/docs/en/rest-api/security.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -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[]
Expand Down Expand Up @@ -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[]
93 changes: 93 additions & 0 deletions x-pack/docs/en/rest-api/security/saml-authenticate-api.asciidoc
Original file line number Diff line number Diff line change
@@ -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
91 changes: 91 additions & 0 deletions x-pack/docs/en/rest-api/security/saml-invalidate-api.asciidoc
Original file line number Diff line number Diff line change
@@ -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
79 changes: 79 additions & 0 deletions x-pack/docs/en/rest-api/security/saml-logout-api.asciidoc
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 8ea92f1

Please sign in to comment.