From 4ee9a44b93422def35067759cdecce1dde8aea44 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Thu, 18 Apr 2019 10:17:21 +0300 Subject: [PATCH 01/16] Add an OIDC realm guide This commit adds a configuration guide for the newly introduced OpenID Connect realm. The guide is similar to the style of the SAML Guide and shares certain parts where applicable (role mappign) It also contains a short section on how the realm can be used for authenticating users without Kibana. --- .../authentication/oidc-guide.asciidoc | 640 ++++++++++++++++++ 1 file changed, 640 insertions(+) create mode 100644 x-pack/docs/en/security/authentication/oidc-guide.asciidoc diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc new file mode 100644 index 0000000000000..ef07bb5a5b7f2 --- /dev/null +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -0,0 +1,640 @@ +[role="xpack"] +[[oidc-guide]] + +== Configuring Single Sign On to the {stack} using OpenID Connect + +The Elastic Stack supports Single Sign On using OpenID Connect via {kib} using +{es} as the backend service that holds most of the functionality. {kib} and {es} +together represent an OpenID Connect Relying Party (RP) that supports the Authorization +Code Flow and the Implicit Flow as these are defined in the OpenID Connect specification. + +This guide assumes that you have an OpenID Connect Provider that you use and where the +Elastic Stack Relying Party will be registered. + +NOTE: The OpenID Connect realm support in {kib} is designed with the expectation that it +will be the primary authentication method for the users of that {kib} instance. The +<> section describes what this entails and how you can set it up to support +other realms if necessary. + +[[oidc-guide-op]] +=== The OpenID Connect Provider + +The OpenID Connect Provider (OP) is the entity in OpenID Connect that is responsible for +authenticating the user and for granting the necessary tokens with the authentication and +user information to be consumed by the Relying Parties. + +In order for the Elastic Stack to be able use your OpenID Connect Provider for authentication, +a trust relationship needs to be established between the OP and the RP. In the OpenID Connect +Provider, this means registering the RP as a client. OpenID Connect defines a dynamic client +registration protocol but this is usually geared towards real-time client registration and +not the trust establishment process for cross security domain single sign on. All OPs will +also allow for the manual registration of an RP as a client, via a user interface or (less often) +via the consumption of a metadata document. + +The process for registering the Elastic Stack RP will be different from OP to OP and following +the provider's relevant documentation is prudent. The most usual piece of information for the +RP that you need to provide for registration are the following: + +- `Relying Party Name`: An arbitrary identifier for the relying party. Neither the specification +nor the Elastic Stack implementation impose any constraints on this value. +- `Redirect URI`: This is the URI where the OP will redirect the user's browser after authentication. The +appropriate value for this will depend on your setup and whether or not {kib} sits behind a proxy or +load balancer, but it will typically be +$\{kibana-url}/api/security/v1/oidc+ where _$\{kibana-url}_ +is the base URL for your {kib} instance. You might also see this called `Callback URI`. + +The registration process will conclude with the RP being assigned a Client Identifier and a Client Secret. +Note these two values as they will be used in the {es} configuration. + +[[oidc-guide-authentication]] +=== Configure {es} for OpenID Connect authentication + +The following is a summary of the configuration steps required in order to enable authentication +using OpenID Connect in {es} + +. <> +. <> +. <> +. <> + +[[oidc-enable-http]] +==== Enable TLS for HTTP + +If your {es} cluster is operating in production mode, then you must +configure the HTTP interface to use SSL/TLS before you can enable OpenID Connect +authentication. + +For more information, see +{ref}/configuring-tls.html#tls-http[Encrypting HTTP Client Communications]. + +[[oidc-enable-token]] +==== Enable the token service + +The {es} SAML implementation makes use of the {es} Token Service. This service +is automatically enabled if you configure TLS on the HTTP interface, and can be +explicitly configured by including the following in your `elasticsearch.yml` file: + +[source, yaml] +------------------------------------------------------------ +xpack.security.authc.token.enabled: true +------------------------------------------------------------ + +[[oidc-create-realm]] +==== Create an OpenID Connect realm + +OpenID Connect based authentication is enabled by configuring the appropriate realm within +the authentication chain for {es} + +This realm has a few mandatory settings, and a number of optional settings. +The available settings are described in detail in the +<>, this guide will explore the most +common settings. + +Create an OpenID Connect (the realm type is `oidc`) realm in your `elasticsearch.yml` file +similar to what is shown below: + +NOTE: The values used below are meant to be an example and might not fit most of the +use cases. The details below the configuration snippet provide insights and suggestions +to help you pick the proper values, depending on your OP configuration. + +[source, yaml] +------------------------------------------------------------------------------------- +xpack.security.authc.realms.oidc.oidc1: + rp.client_id: "the_client_id" + rp.response_type: code + rp.redirect_uri: "https://kibana.example.org:5601/api/security/v1/oidc" + op.authorization_endpoint: "https://op.example.org/oauth2/v1/authorize" + op.token_endpoint: "https://op.example.org/oauth2/v1/token" + op.userinfo_endpoint: "https://op.example.org/oauth2/v1/userinfo" + op.endsession_endpoint: "https://op.example.org/oauth2/v1/logout" + op.issuer: "https://op.example.org" + op.jwkset_path: oidc/jwkset.json + claims.principal: sub + claims.groups: "http://example.info/claims/groups" +------------------------------------------------------------------------------------- + +The configuration values used in the example above are: + +xpack.security.authc.realms.oidc.oidc1:: + This defines a new `oidc` authentication realm named "oidc1". + See <> for more explanation of realms. + +order:: + You should define a unique order on each realm in your authentication chain. + It is recommended that the OpenID Connect realm be at the bottom of your authentication + chain (that is, that it has the _highest_ order). + +rp.client_id:: + This, usually opaque, arbitrary string, is the Client Identifier that was assigned to the Elastic Stack RP by the OP upon + registration. + +rp.response_type:: + This is an identifier that controls which OpenID Connect authentication flow this RP supports and also + which flow this PR requests the OP should follow too. Supported values are + - `code`, which means that we want to use the Authorization Code flow + - `id_token token` which means that we want to use the Implicit flow and we also request an oAuth2 + access token from the OP, that we can potentially use for follow up requests ( UserInfo ) + - `id_token` which means that we want to use the Implicit flow, but are not interested in getting + an oAuth2 token too. + +rp.redirect_uri:: + The redirect URI where the OP will redirect the browser after authentication. This needs to be + _exactly_ the same as the one <> and will + typically be +$\{kibana-url}/api/security/v1/oidc+ where _$\{kibana-url}_ is the base URL for your {kib} instance + +op.authorization_endpoint:: + The URL for the Authorization Endpoint in the OpenID Connect Provider. This is where the user's browser + will be redirected to start the authentication process. + +op.token_endpoint:: + The URL for the Token Endpoint in the OpenID Connect Provider. This is the endpoint where + {es} will send a request to exchange the code for an ID Token, in the case where the Authorization Code + flow is used. + +op.userinfo_endpoint:: + The URL for the UserInfo Endpoint in the OpenID Connect Provider. This is the endpoint of the OP that + can be queried to get further user information, if required. + +op.endsession_endpoint:: + The URL to the End Session Endpoint in the OpenID Connect Provider. This is the endpoint where the user's + browser will be redirected after local logout, if the realm is configured for RP initiated Single Logout and + the OP supports it. + +op.jwkset_path:: + The path to a file containing a JSON Web Key Set with the key material that the OpenID Connect + Provider uses for signing tokens and claims responses. The path is resolved relative to the {es} + config directory. + {es} will automatically monitor this file for changes and will reload the configuration whenever + it is updated. + +claims.principal:: See <>. +claims.groups:: See <>. + +A final piece of configuration of the OpenID Connect realm is to set the `Client Secret` that was assigned +to the RP during registration in the OP. This is a secure setting and as such is not defined in the realm +configuration in `elasticsearch.yml` but added to the {ref}/secure-settings.html[elasticsearch keystore]. +For instance + + +[source,sh] +---- +bin/elasticsearch-keystore add xpack.security.authc.realms.oidc.oidc1.client_secret +---- + + +NOTE: According to the OpenID Connect specification, the OP should also make their configuration +available at a well known URL, which is the concatenation of their `Issuer` value with the +`.well-known/openid-configuration` string. For example: `https://op.org.com/.well-known/openid-configuration` +That document should contain all the necessary information to configure the OpenID Connect realm in {es}. + + +[[oidc-claims-mapping]] +==== Claims mapping + +===== Claims and scopes + +When authenticating to {kib} using OpenID Connect, the OP will provide information about the user +in the form of OpenID Connect Claims, that can be included either in the ID Token, or be retrieved from the +UserInfo endpoint of the OP. The claim is defined as a piece of information asserted by the OP +for the authenticated user. Simply put, a claim is a name/value pair that contains information about +the user. Related to claims, we also have the notion of OpenID Connect Scopes. Scopes are identifiers +that are used to request access to specific lists of claims. The standard defines a set of scope +identifiers that can be requested. The only mandatory one is `openid`, while commonly used ones are +`profile` ( requesting access to the `name`,`family_name`,`given_name`,`middle_name`,`nickname`, +`preferred_username`,`profile`,`picture`,`website`,`gender`,`birthdate`,`zoneinfo`,`locale`,`updated_at` claims), +and `email` (requesting access to the `email` and `email_verified` claims). The process is that +the RP requests specific scopes during the authentication request, and if the OP Privacy Policy +allows it and the authenticating user consents to it, the related claims are returned to the +RP, either in the ID Token, or as a UserInfo response. + +The list of the supported claims will vary depending on the OP you are using, but one should expect +the https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[Standard Claims] to be +largely supported. + +[[oidc-claim-to-property]] +===== Mapping claims to user properties + +The goal of claims mapping is to configure {es} in such a way as to be able to map the values of +specified returned claims to one of the supported <> . These user +properties are then utilized to identify the user in the {kib} UI or the audit logs, and can also +be used to create <> rules. + +The recommended steps for configuring OpenID Claims mapping are as follows: + +. Consult your OP configuration to see what claims it might support. Note that + the list provided in the OPs metadata, or in the configuration page of the OP + is a list of potentially supported claims, but for privacy reasons it might + not be a complete one, or not all supported claims will be available for all + authenticated users. + +. Read through the list of <> that {es} + supports, and decide which of them are useful to you, and can be provided by + your OP in the form of claims. At a _minimum_, the `principal` user property + is required. + +. Configure your OP to "release" those claims to your Elastic Stack Relying + party. This process greatly varies by provider - some will allow for static + configuration while others will support that the RP requests the scopes that + correspond to the claims to be "released" on authentication time. See + <> on how to configure the scopes to + request. To ensure interoperability and minimize the errors, you should only + request scopes that the OP supports. + +. Configure the OpenID Connect realm in {es} to associate the {es} user properties (see + <> below), to the name of the claims that your + OP will release. In the example above, we have configured the `principal` and + `groups` user properties as follows: + + .. `claims.principal: sub` : This instructs {es} to look for the OpenID Connect claim named `sub` + in the ID Token that the OP issued for the user ( or in the UserInfo response ) and assign the + value of this claim to the `principal` user property. `sub` is a commonly used claim for the + principal property as it is an identifier of the user in the OP and it is also a required + claim of the ID Token, thus offering guarantees that it will be available. It is, however, + only used as an example here, other claims can also very well be used for the same mapping. + + .. `claims.groups: "http://example.info/claims/groups"` : Similarly, this instructs {es} to look + for the claim with the name `http://example.info/claims/groups` (note that this is a URI - an + identifier, treated as a string and not a URL pointing to a location that will be retrieved) + either in the ID Token or in the UserInfo response, and map the value(s) of it to the user + property `groups` in {es}. There is no standard claim in the specification that is used for + expressing roles or group memberships of the authenticated user in the OP, so the name of the + claim that should be mapped here, will greatly vary between providers. Consult your OP + documentation for more details. + +[[oidc-user-properties]] +===== {es} user properties + +The {es} OpenID Connect realm can be configured to map OpenID Connect claims to the +following properties on the authenticated user: + +principal:: _(Required)_ + This is the _username_ that will be applied to a user that authenticates + against this realm. + The `principal` appears in places such as the {es} audit logs. + +NOTE: If the principal property fails to be mapped from a claim, the authentication fails. + +groups:: _(Recommended)_ + If you wish to use your OP's concept of groups or roles as the basis for a + user's {es} privileges, you should map them with this property. + The `groups` are passed directly to your <> + +name:: _(Optional)_ The user's full name. +mail:: _(Optional)_ The user's email address. +dn:: _(Optional)_ The user's X.500 _Distinguished Name_. + + +===== Extracting partial values from OpenID Connect claims + +There are some occasions where the value of a claim may contain more information +than you wish to use within {es}. A common example of this is one where the +OP works exclusively with email addresses, but you would like the user's +`principal` to use the _local-name_ part of the email address. +For example if their email address was `james.wong@staff.example.com`, then you +would like their principal to simply be `james.wong`. + +This can be achieved using the `claim_patterns` setting in the {es} +realm, as demonstrated in the realm configuration below: + +[source, yaml] +------------------------------------------------------------------------------------- +xpack.security.authc.realms.oidc.oidc1: + rp.client_id: "the_client_id" + rp.response_type: code + rp.redirect_uri: "https://kibana.example.org:5601/api/security/v1/oidc" + op.authorization_endpoint: "https://op.example.org/oauth2/v1/authorize" + op.token_endpoint: "https://op.example.org/oauth2/v1/token" + op.userinfo_endpoint: "https://op.example.org/oauth2/v1/userinfo" + op.endsession_endpoint: "https://op.example.org/oauth2/v1/logout" + op.issuer: "https://op.example.org" + op.jwkset_path: oidc/jwkset.json + claims.principal: email_verified + claim_patterns.principal: "^([^@]+)@staff\\.example\\.com$" +------------------------------------------------------------------------------------- + +In this case, the user's `principal` is mapped from the `email_verified` claim, but a +regular expression is applied to the value before it is assigned to the user. +If the regular expression matches, then the result of the first group is used as +effective value. If the regular expression does not match then the claim +mapping fails. + +In this example, the email address must belong to the `staff.example.com` domain, +and then the local-part (anything before the `@`) is used as the principal. +Any users who try to login using a different email domain will fail because the +regular expression will not match against their email address, and thus their +principal user property - which is mandatory - will not be populated. + +IMPORTANT: Small mistakes in these regular expressions can have significant +security consequences. For example, if we accidentally left off the trailing +`$` from the example above, then we would match any email address where the +domain starts with `staff.example.com`, and this would accept an email +address such as `admin@staff.example.com.attacker.net`. It is important that +you make sure your regular expressions are as precise as possible so that +you do not inadvertently open an avenue for user impersonation attacks. + +[[3rd-party-login]] +==== Third Party Initiated Single Sign On + +The Open ID Connect realm in {es} supports 3rd party initiated login as described in the +https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin[relevant specification] + +This allows the OP itself or another, third party other than the RP, to initiate the authentication +process while requesting the OP to be used for the authentication. Please note that the Elastic +Stack RP should already be configured for this OP, in order for this process to succeed. + + +[[oidc-logout]] +==== OpenID Connect Logout + +The OpenID Connect realm in {es} supports RP-Initiated Logout Functionality as +described in the +https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[relevant part of the specification] + +In this process, the OpenID Connect RP (the Elastic Stack in this case) will redirect the user's +browser to predefined URL of the OP after successfully completing a local logout. The OP can then +logout the user also, depending on the configuration, and should finally redirect the user back to the +RP. The `op.endsession_endpoint` in the realm configuration determines the URL in the OP that the browser +will be redirected and the `rp.post_logout_redirect_uri` setting determines the URL to redirect back +the user after OP logs them out. + +When configuring `rp.post_logout_redirect_uri`, care should be taken to not point this to a URL that +will trigger re-authentication of the user. For instance, when using OpenID Connect to support +Single Sign On to {kib}, this could be set to +$\{kibana-url}/logged_out+ that will show a user +friendly message to the user. + +[[oidc-role-mapping]] +=== Configuring role mappings + +When a user authenticates using OpenID Connect, they are identified to the Elastic Stack, +but this does not automatically grant them access to perform any actions or +access any data. + +Your OpenID Connect users cannot do anything until they are assigned roles. This can be done +through either the +{ref}/security-api-put-role-mapping.html[add role mapping API], or with +<>. + +NOTE: You cannot use {stack-ov}/mapping-roles.html#mapping-roles-file[role mapping files] +to grant roles to users authenticating via OpenID Connect. + +This is an example of a simple role mapping that grants the `kibana_user` role +to any user who authenticates against the `oidc1` OpenID Conenct realm: + +[source,js] +-------------------------------------------------- +PUT /_security/role_mapping/oidc-kibana +{ + "roles": [ "kibana_user" ], + "enabled": true, + "rules": { + "field": { "realm.name": "oidc1" } + } +} +-------------------------------------------------- +// CONSOLE +// TEST + + +The user properties that are mapped via the realm configuration are used to process +role mapping rules, and these rules determine which roles a user is granted. + +The user fields that are provided to the role +mapping are derived from the OpenID Connect claims as follows: + +- `username`: The `principal` user property +- `dn`: The `dn` user property +- `groups`: The `groups` user property +- `metadata`: See <> + +For more information, see <> and +{ref}/security-api.html#security-role-mapping-apis[role mapping APIs]. + +If your OP has the ability to provide groups or roles to RPs via tha use of +an OpenID Claim, then you should map this claim to the `claims.groups` setting in +the {es} realm (see <>), and then make use of it in a role mapping +as per the example below. + +This mapping grants the {es} `finance_data` role, to any users who authenticate +via the `oidc1` realm with the `finance-team` group membership. + +[source,js] +-------------------------------------------------- +PUT /_security/role_mapping/oidc-finance +{ + "roles": [ "finance_data" ], + "enabled": true, + "rules": { "all": [ + { "field": { "realm.name": "oidc1" } }, + { "field": { "groups": "finance-team" } } + ] } +} +-------------------------------------------------- +// CONSOLE +// TEST + +If your users also exist in a repository that can be directly accessed by {es} +(such as an LDAP directory) then you can use +<> instead of role mappings. + +In this case, you perform the following steps: +1. In your OpenID Connect realm, assign a claim to act as the lookup userid, + by configuring the `claims.principal` setting. +2. Create a new realm that can lookup users from your local repository (e.g. an + `ldap` realm) +3. In your OpenID Connect realm, set `authorization_realms` to the name of the realm you + created in step 2. + +[[oidc-user-metadata]] +=== User metadata + +By default users who authenticate via OpenID Connect will have some additional metadata +fields. These will include every OpenID Claim that is provided in the authentication response +(regardless of whether it is mapped to an {es} user property), will be added +as the metadata field `oidc(claim_name)` where "claim_name" is the name of the +claim as it was contained in the ID Token or in the User Info response. Note that these will +include all the https://openid.net/specs/openid-connect-core-1_0.html#IDToken[ID Token claims] +that pertain to the authentication event, rather than the user themselves. + + +This behaviour can be disabled by adding `populate_user_metadata: false` to as +a setting in the oidc realm. + +[[oidc-kibana]] +=== Configuring {kib} + +OpenID Connect authentication in {kib} requires a small number of additional settings +in addition to the standard {kib} security configuration. The +{kibana-ref}/using-kibana-with-security.html[{kib} security documentation] +provides details on the available configuration options that you can apply. + +In particular, since your {es} nodes have been configured to use TLS on the HTTP +interface, you must configure {kib} to use a `https` URL to connect to {es}, and +you may need to configure `elasticsearch.ssl.certificateAuthorities` to trust +the certificates that {es} has been configured to use. + +OpenID Connect authentication in {kib} is also subject to the +`xpack.security.sessionTimeout` setting that is described in the {kib} security +documentation, and you may wish to adjust this timeout to meet your local needs. + +The three additional settings that are required for OpenID Connect support are shown below: + +[source, yaml] +------------------------------------------------------------ +xpack.security.authProviders: [oidc] +xpack.security.auth.oidc.realm: "oidc1" +server.xsrf.whitelist: [/api/security/v1/oidc] +------------------------------------------------------------ + +The configuration values used in the example above are: + +`xpack.security.authProviders`:: +Set this to `[ oidc ]` to instruct {kib} to use OpenID Connect Single Sign On as the +authentication method. This instructs kibana to attempt and initiate an SSO flow +everytime a user attempts to access a URL in Kibana, if the user is not already +authenticated. If you wish to allow users to login with a username and password +also, then you'd need to enable the `basic` authProvider too by setting + +[source, yaml] +------------------------------------------------------------ +xpack.security.authProviders: [oidc, basic] +------------------------------------------------------------ + +This will allow users that haven't already authenticated with OpenID Connect to +navigate directly to the `/login` page in {kib} in order to use the login form. + +`xpack.security.auth.oidc.realm`:: +The name of the OpenID Connect realm in {es} that should handle authentication +for this Kibana instance. + +`server.xsrf.whitelist`:: +{kib} has in-built protection against _Cross Site Request Forgery_ attacks which +are designed to prevent the {kib} server from processing requests that +originated from outside the {kib} application. +In order to support OpenID Connect messages that originate from your +OP or a third party (see <<3rd-party-login>>, we need to explicitly _whitelist_ the +OpenID Connect authentication endpoint within {kib}, so that the {kib} server will +not reject these external messages. + + +=== OpenID Connect without {kib} + +The OpenID Connect realm 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 OpenID +Connect REST APIs in order to authenticate the users to {es}, with OpenID Connect. + +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 with +an {es} access token to be used as credentials for subsequent calls to {es} and a +refresh token allowing to get new {es} access tokens for the user once the current one +expires. + +NOTE: The {es} Token Service can be seen as a minimal oAuth2 authorization server +and the access token and refresh token mentioned above are tokens that pertain +_only_ to this authorization server, are generated and consumed _only_ by {es} +and are in no way related to the tokens ( access token and ID Token ) that the +OpenID Connect Provider issues. + +==== Register the RP with an OpenID Connect Provider + +The Relying Party ( {es} and the custom web app ) will need to be registered as +client with the OpenID Connect Provider. Note that when registering the +`Redirect URI`, it needs to be a URL in the custom web app. + +==== OpenID Connect Realm + +As before, an OpenID Connect realm needs to be created and configured accordingly +in {es}. See <> + +==== 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 OpenID Connect Provider ). The OpenID Connect +APIs require authentication and the necessary authorization level for the authenticated +user. For this reason, a Service Account user needs to be created and assigned a role +that gives them the `manage_oidc` cluster privilege. The use of the `manage_token` +cluster privilege will be necessary after the authentication takes place, so that the +the user can maintain access or be subsequently logged out. + +[source,js] +-------------------------------------------------- +POST /_security/role/facilitator-role +{ + "cluster" : ["manage_oidc", "manage_token"] +} +-------------------------------------------------- +// CONSOLE + + +[source,js] +-------------------------------------------------- +POST /_security/user/facilitator +{ + "password" : "", + "roles" : [ "facilitator-role"] +} +-------------------------------------------------- +// CONSOLE + + +==== Handling the authentication flow + +On a high level, the custom web application would need to perform the following steps in order to +authenticate a user with OpenID Connect: + +. Make an HTTP POST request to `_security/oidc/prepare`, authenticating as the `facilitator` user, using the name of the +OpenID Connect realm in the {es} configuration in the request body. See the +<> for more details ++ +[source,js] +-------------------------------------------------- +POST /_security/oidc/prepare +{ + "realm" : "oidc1" +} +-------------------------------------------------- +// CONSOLE ++ +. Handle the response to `/_security/oidc/prepare`. The response from {es} will contain 3 parameters: + `redirect`, `state`, `nonce`. The custom web application would need to store the values for `state` + and `nonce` in the user's session (client side in a cookie or server side if session information is + persisted this way) and redirect the user's browser to the URL that will be contained in the + `redirect` value. +. Handle a subsequent response from the OP. After the user is successfully authenticated with the + OpenID Connect Provider, they will be redirected back to the callback/redirect URI. Upon receiving + this HTTP GET request, the custom web app will need to make an HTTP POST request to + `_security/oidc/authenticate`, again - authenticating as the `facilitator` user passing the URL of + the GET request it received as a parameter, along with the values for `nonce` and `state` it had + saved in the user's session previously. + See <> for more details ++ +[source,js] +----------------------------------------------------------------------- +POST /_security/oidc/authenticate +{ + "redirect_uri" : "https://oidc-kibana.elastic.co:5603/api/security/v1/oidc?code=jtI3Ntt8v3_XvcLzCFGq&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I", + "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I", + "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM" +} +----------------------------------------------------------------------- +// CONSOLE ++ +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 <> +. At some point, if necessary, the custom web application can log the user out by using the + <> passing the access token and refresh token as parameters, as seen below ++ +[source,js] +-------------------------------------------------- +POST /_security/oidc/logout +{ + "token" : "dGhpcyBpcyBub3QgYSByZWFsIHRva2VuIGJ1dCBpdCBpcyBvbmx5IHRlc3QgZGF0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==", + "refresh_token": "vLBPvmAB6KvwvJZr27cS" +} +-------------------------------------------------- +// CONSOLE ++ +If the realm is configured accordingly, this may result in a response with a `redirect` parameter indicating where +the user needs to be redirected in the OP in order to complete the logout process. \ No newline at end of file From 30ab623269fae687ca651875a461af64e321a6df Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Tue, 23 Apr 2019 00:31:48 +0300 Subject: [PATCH 02/16] mute doc tests --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index ef07bb5a5b7f2..5568e21aa07a1 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -595,6 +595,7 @@ POST /_security/oidc/prepare } -------------------------------------------------- // CONSOLE +// TEST[skip:These are properly tested in the OpenIDConnectIT suite] + . Handle the response to `/_security/oidc/prepare`. The response from {es} will contain 3 parameters: `redirect`, `state`, `nonce`. The custom web application would need to store the values for `state` @@ -619,6 +620,7 @@ POST /_security/oidc/authenticate } ----------------------------------------------------------------------- // CONSOLE +// TEST[skip:These are properly tested in the OpenIDConnectIT suite] + 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 @@ -635,6 +637,7 @@ POST /_security/oidc/logout } -------------------------------------------------- // CONSOLE +// TEST[skip:These are properly tested in the OpenIDConnectIT suite] + If the realm is configured accordingly, this may result in a response with a `redirect` parameter indicating where the user needs to be redirected in the OP in order to complete the logout process. \ No newline at end of file From 23d006a5405a29c6d2d6d91882f46634170bbce4 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Tue, 23 Apr 2019 00:33:16 +0300 Subject: [PATCH 03/16] SAML->OIDC --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 5568e21aa07a1..df8634951a393 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -69,7 +69,7 @@ For more information, see [[oidc-enable-token]] ==== Enable the token service -The {es} SAML implementation makes use of the {es} Token Service. This service +The {es} OpenID Connect implementation makes use of the {es} Token Service. This service is automatically enabled if you configure TLS on the HTTP interface, and can be explicitly configured by including the following in your `elasticsearch.yml` file: From 3e73e730cd9c5eef782c43524fc0077ae5da0a0f Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Tue, 23 Apr 2019 17:39:58 +0300 Subject: [PATCH 04/16] correct typo in command --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index df8634951a393..c1be616b4594a 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -177,7 +177,7 @@ For instance [source,sh] ---- -bin/elasticsearch-keystore add xpack.security.authc.realms.oidc.oidc1.client_secret +bin/elasticsearch-keystore add xpack.security.authc.realms.oidc.oidc1.rp.client_secret ---- @@ -640,4 +640,4 @@ POST /_security/oidc/logout // TEST[skip:These are properly tested in the OpenIDConnectIT suite] + If the realm is configured accordingly, this may result in a response with a `redirect` parameter indicating where -the user needs to be redirected in the OP in order to complete the logout process. \ No newline at end of file +the user needs to be redirected in the OP in order to complete the logout process. From 448028d3e2332e898c28460ba0e2099802e0d318 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Wed, 24 Apr 2019 18:56:47 +0300 Subject: [PATCH 05/16] Address feedback --- x-pack/docs/build.gradle | 15 ++++ .../rest-api/security/authenticate.asciidoc | 4 +- .../security/oidc-authenticate-api.asciidoc | 2 +- .../security/oidc-logout-api.asciidoc | 2 +- .../oidc-prepare-authentication-api.asciidoc | 20 +++--- .../authentication/oidc-guide.asciidoc | 68 ++++++++++--------- 6 files changed, 65 insertions(+), 46 deletions(-) diff --git a/x-pack/docs/build.gradle b/x-pack/docs/build.gradle index 5e56414afed24..7358d750fe0ed 100644 --- a/x-pack/docs/build.gradle +++ b/x-pack/docs/build.gradle @@ -70,6 +70,7 @@ File xpackResources = new File(xpackProject('plugin').projectDir, 'src/test/reso project.copyRestSpec.from(xpackResources) { include 'rest-api-spec/api/**' } +File jwks = new File(xpackProject('test:idp-fixture').projectDir, 'oidc/op-jwks.json') integTestCluster { setting 'xpack.security.enabled', 'true' setting 'xpack.security.authc.api_key.enabled', 'true' @@ -78,9 +79,23 @@ integTestCluster { setting 'xpack.monitoring.exporters._local.type', 'local' setting 'xpack.monitoring.exporters._local.enabled', 'false' setting 'xpack.license.self_generated.type', 'trial' + setting 'xpack.security.authc.realms.file.file.order', '0' + setting 'xpack.security.authc.realms.native.native.order', '1' + setting 'xpack.security.authc.realms.oidc.oidc1.order', '2' + setting 'xpack.security.authc.realms.oidc.oidc1.op.name', 'c2id-implicit' + setting 'xpack.security.authc.realms.oidc.oidc1.op.issuer', 'http://127.0.0.1:8080' + setting 'xpack.security.authc.realms.oidc.oidc1.op.authorization_endpoint', "http://127.0.0.1:8080/c2id-login" + setting 'xpack.security.authc.realms.oidc.oidc1.op.token_endpoint', "http://127.0.0.1:8080/c2id/token" + setting 'xpack.security.authc.realms.oidc.oidc1.op.jwkset_path', 'op-jwks.json' + setting 'xpack.security.authc.realms.oidc.oidc1.rp.redirect_uri', 'https://my.fantastic.rp/cb' + setting 'xpack.security.authc.realms.oidc.oidc1.rp.client_id', 'elasticsearch-rp' + keystoreSetting 'xpack.security.authc.realms.oidc.oidc1.rp.client_secret', 'b07efb7a1cf6ec9462afe7b6d3ab55c6c7880262aa61ac28dded292aca47c9a2' + setting 'xpack.security.authc.realms.oidc.oidc1.rp.response_type', 'id_token' + setting 'xpack.security.authc.realms.oidc.oidc1.claims.principal', 'sub' setupCommand 'setupTestAdmin', 'bin/elasticsearch-users', 'useradd', 'test_admin', '-p', 'x-pack-test-password', '-r', 'superuser' waitCondition = waitWithAuth + extraConfigFile 'op-jwks.json', jwks } diff --git a/x-pack/docs/en/rest-api/security/authenticate.asciidoc b/x-pack/docs/en/rest-api/security/authenticate.asciidoc index 51b0d64419453..d23c410a62389 100644 --- a/x-pack/docs/en/rest-api/security/authenticate.asciidoc +++ b/x-pack/docs/en/rest-api/security/authenticate.asciidoc @@ -46,11 +46,11 @@ The following example output provides information about the "rdeniro" user: "metadata": { }, "enabled": true, "authentication_realm": { - "name" : "default_file", + "name" : "file", "type" : "file" }, "lookup_realm": { - "name" : "default_file", + "name" : "file", "type" : "file" } } diff --git a/x-pack/docs/en/rest-api/security/oidc-authenticate-api.asciidoc b/x-pack/docs/en/rest-api/security/oidc-authenticate-api.asciidoc index 0efb2b23145f7..bc60e4fbf231d 100644 --- a/x-pack/docs/en/rest-api/security/oidc-authenticate-api.asciidoc +++ b/x-pack/docs/en/rest-api/security/oidc-authenticate-api.asciidoc @@ -51,7 +51,7 @@ POST /_security/oidc/authenticate } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] +// TEST[catch:unauthorized] The following example output contains the access token that was generated in response, the amount of time (in seconds) that the token expires in, the type, and the refresh token: diff --git a/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc b/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc index 6f5288a135f2a..0acc2b6675acd 100644 --- a/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc +++ b/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc @@ -39,7 +39,7 @@ POST /_security/oidc/logout } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] +// TEST[catch:bad_request] The following example output of the response contains the URI pointing to the End Session Endpoint of the OpenID Connect Provider with all the parameters of the Logout Request, as HTTP GET parameters diff --git a/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc b/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc index aeb400ce97ef1..7a86eb9713ae6 100644 --- a/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc +++ b/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc @@ -57,20 +57,19 @@ POST /_security/oidc/prepare } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] - The following example output of the response contains the URI pointing to the Authorization Endpoint of the OpenID Connect Provider with all the parameters of the Authentication Request, as HTTP GET parameters [source,js] -------------------------------------------------- { - "redirect" : "https://op-provider.org/login?scope=openid&response_type=code&redirect_uri=http%3A%2F%2Foidc-kibana.elastic.co%3A5603%2Fkmi%2Fapi%2Fsecurity%2Fv1%2Foidc&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=0o43gasov3TxMWJOt839", + "redirect" : "http://127.0.0.1:8080/c2id-login?scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=elasticsearch-rp", "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I", "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM" } -------------------------------------------------- -// NOTCONSOLE +// TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/$body.state/] +// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/$body.nonce/] The following example generates an authentication request for the OpenID Connect Realm `oidc1`, where the values for the state and the nonce have been generated by the client @@ -85,7 +84,6 @@ POST /_security/oidc/prepare } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] The following example output of the response contains the URI pointing to the Authorization Endpoint of the OpenID Connect Provider with all the parameters of the Authentication Request, as HTTP GET parameters @@ -93,12 +91,12 @@ OpenID Connect Provider with all the parameters of the Authentication Request, a [source,js] -------------------------------------------------- { - "redirect" : "https://op-provider.org/login?scope=openid&response_type=code&redirect_uri=http%3A%2F%2Foidc-kibana.elastic.co%3A5603%2Fkmi%2Fapi%2Fsecurity%2Fv1%2Foidc&state=lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO&nonce=zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5&client_id=0o43gasov3TxMWJOt839", + "redirect" : "http://127.0.0.1:8080/c2id-login?scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO&nonce=zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5&client_id=elasticsearch-rp", "state" : "lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO", "nonce" : "zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5" } -------------------------------------------------- -// NOTCONSOLE +// TESTRESPONSE The following example generates an authentication request for a 3rd party initiated single sign on, specifying the issuer that should be used for matching the appropriate OpenID Connect Authentication realm @@ -107,12 +105,11 @@ issuer that should be used for matching the appropriate OpenID Connect Authentic -------------------------------------------------- POST /_security/oidc/prepare { - "issuer" : "https://op-issuer.org:8800", + "iss" : "http://127.0.0.1:8080", "login_hint": "this_is_an_opaque_string" } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] The following example output of the response contains the URI pointing to the Authorization Endpoint of the OpenID Connect Provider with all the parameters of the Authentication Request, as HTTP GET parameters @@ -120,9 +117,10 @@ OpenID Connect Provider with all the parameters of the Authentication Request, a [source,js] -------------------------------------------------- { - "redirect" : "https://op-provider.org/login?scope=openid&response_type=code&redirect_uri=http%3A%2F%2Foidc-kibana.elastic.co%3A5603%2Fkmi%2Fapi%2Fsecurity%2Fv1%2Foidc&state=lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO&nonce=zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5&client_id=0o43gasov3TxMWJOt839&login_hint=this_is_an_opaque_string", + "redirect" : "http://127.0.0.1:8080/c2id-login?login_hint=this_is_an_opaque_string&scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=elasticsearch-rp", "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I", "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM" } -------------------------------------------------- -// NOTCONSOLE \ No newline at end of file +// TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/$body.state/] +// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/$body.nonce/] \ No newline at end of file diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index c1be616b4594a..2f3fe48d21cc4 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -42,7 +42,7 @@ appropriate value for this will depend on your setup and whether or not {kib} si load balancer, but it will typically be +$\{kibana-url}/api/security/v1/oidc+ where _$\{kibana-url}_ is the base URL for your {kib} instance. You might also see this called `Callback URI`. -The registration process will conclude with the RP being assigned a Client Identifier and a Client Secret. +At the end of the registration process, the OP will assign aClient Identifier and a Client Secret for the RP ({stack}) to use. Note these two values as they will be used in the {es} configuration. [[oidc-guide-authentication]] @@ -92,13 +92,14 @@ common settings. Create an OpenID Connect (the realm type is `oidc`) realm in your `elasticsearch.yml` file similar to what is shown below: -NOTE: The values used below are meant to be an example and might not fit most of the -use cases. The details below the configuration snippet provide insights and suggestions +NOTE: The values used below are meant to be an example and are not intended to apply to +every use case. The details below the configuration snippet provide insights and suggestions to help you pick the proper values, depending on your OP configuration. [source, yaml] ------------------------------------------------------------------------------------- xpack.security.authc.realms.oidc.oidc1: + order: 2 rp.client_id: "the_client_id" rp.response_type: code rp.redirect_uri: "https://kibana.example.org:5601/api/security/v1/oidc" @@ -129,12 +130,16 @@ rp.client_id:: rp.response_type:: This is an identifier that controls which OpenID Connect authentication flow this RP supports and also - which flow this PR requests the OP should follow too. Supported values are - - `code`, which means that we want to use the Authorization Code flow - - `id_token token` which means that we want to use the Implicit flow and we also request an oAuth2 - access token from the OP, that we can potentially use for follow up requests ( UserInfo ) - - `id_token` which means that we want to use the Implicit flow, but are not interested in getting - an oAuth2 token too. + which flow this PR requests the OP should follow. Supported values are + - `code`, which means that the RP wants to use the Authorization Code flow. If your OP supports the + Authorization Code flow, you should select this in favor of the Implicit Flow. + - `id_token token` which means that the RP wants to use the Implicit flow and we also request an oAuth2 + access token from the OP, that we can potentially use for follow up requests ( UserInfo ). This + should be selected if the OP offers a UserInfo endpoint in its configuration, or if you know that + the claims you will need to use for role mapping are not available in the ID Token. + - `id_token` which means that the RP wants to use the Implicit flow, but is not interested in getting + an oAuth2 token too. Select this if you are certain that all necessary claims will be contained in + the ID Token or if the OP doesn't offer a User Info endpoint. rp.redirect_uri:: The redirect URI where the OP will redirect the browser after authentication. This needs to be @@ -143,28 +148,30 @@ rp.redirect_uri:: op.authorization_endpoint:: The URL for the Authorization Endpoint in the OpenID Connect Provider. This is where the user's browser - will be redirected to start the authentication process. + will be redirected to start the authentication process. The value for this setting should be provided by your + OpenID Connect Provider. op.token_endpoint:: The URL for the Token Endpoint in the OpenID Connect Provider. This is the endpoint where {es} will send a request to exchange the code for an ID Token, in the case where the Authorization Code - flow is used. + flow is used. The value for this setting should be provided by your OpenID Connect Provider. op.userinfo_endpoint:: - The URL for the UserInfo Endpoint in the OpenID Connect Provider. This is the endpoint of the OP that - can be queried to get further user information, if required. + (Optional) The URL for the UserInfo Endpoint in the OpenID Connect Provider. This is the endpoint of the OP that + can be queried to get further user information, if required. The value for this setting should be provided by your + OpenID Connect Provider. op.endsession_endpoint:: - The URL to the End Session Endpoint in the OpenID Connect Provider. This is the endpoint where the user's + (Optional) The URL to the End Session Endpoint in the OpenID Connect Provider. This is the endpoint where the user's browser will be redirected after local logout, if the realm is configured for RP initiated Single Logout and - the OP supports it. + the OP supports it. The value for this setting should be provided by your OpenID Connect Provider. op.jwkset_path:: The path to a file containing a JSON Web Key Set with the key material that the OpenID Connect Provider uses for signing tokens and claims responses. The path is resolved relative to the {es} config directory. {es} will automatically monitor this file for changes and will reload the configuration whenever - it is updated. + it is updated. The value for this setting should be provided by your OpenID Connect Provider. claims.principal:: See <>. claims.groups:: See <>. @@ -214,9 +221,9 @@ largely supported. ===== Mapping claims to user properties The goal of claims mapping is to configure {es} in such a way as to be able to map the values of -specified returned claims to one of the supported <> . These user -properties are then utilized to identify the user in the {kib} UI or the audit logs, and can also -be used to create <> rules. +specified returned claims to one of the <> that are supported +by {es}. These user properties are then utilized to identify the user in the {kib} UI or the audit +logs, and can also be used to create <> rules. The recommended steps for configuring OpenID Claims mapping are as follows: @@ -231,13 +238,13 @@ The recommended steps for configuring OpenID Claims mapping are as follows: your OP in the form of claims. At a _minimum_, the `principal` user property is required. -. Configure your OP to "release" those claims to your Elastic Stack Relying +. Configure your OP to "release" those claims to your {stack} Relying party. This process greatly varies by provider - some will allow for static configuration while others will support that the RP requests the scopes that correspond to the claims to be "released" on authentication time. See <> on how to configure the scopes to request. To ensure interoperability and minimize the errors, you should only - request scopes that the OP supports. + request scopes that the OP supports, and which you intend to map to {es} user properties. . Configure the OpenID Connect realm in {es} to associate the {es} user properties (see <> below), to the name of the claims that your @@ -249,7 +256,7 @@ The recommended steps for configuring OpenID Claims mapping are as follows: value of this claim to the `principal` user property. `sub` is a commonly used claim for the principal property as it is an identifier of the user in the OP and it is also a required claim of the ID Token, thus offering guarantees that it will be available. It is, however, - only used as an example here, other claims can also very well be used for the same mapping. + only used as an example here, the OP may provide another claim that is a better fit for your needs. .. `claims.groups: "http://example.info/claims/groups"` : Similarly, this instructs {es} to look for the claim with the name `http://example.info/claims/groups` (note that this is a URI - an @@ -257,7 +264,7 @@ The recommended steps for configuring OpenID Claims mapping are as follows: either in the ID Token or in the UserInfo response, and map the value(s) of it to the user property `groups` in {es}. There is no standard claim in the specification that is used for expressing roles or group memberships of the authenticated user in the OP, so the name of the - claim that should be mapped here, will greatly vary between providers. Consult your OP + claim that should be mapped here, will vary greatly between providers. Consult your OP documentation for more details. [[oidc-user-properties]] @@ -455,7 +462,7 @@ include all the https://openid.net/specs/openid-connect-core-1_0.html#IDToken[ID that pertain to the authentication event, rather than the user themselves. -This behaviour can be disabled by adding `populate_user_metadata: false` to as +This behaviour can be disabled by adding `populate_user_metadata: false` as a setting in the oidc realm. [[oidc-kibana]] @@ -523,7 +530,7 @@ This section describes how a custom web application could use the relevant OpenI Connect REST APIs in order to authenticate the users to {es}, with OpenID Connect. 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 with +{es} and in principle exchange a SAML or OpenID Connect Authentication response for an {es} access token to be used as credentials for subsequent calls to {es} and a refresh token allowing to get new {es} access tokens for the user once the current one expires. @@ -595,7 +602,6 @@ POST /_security/oidc/prepare } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] + . Handle the response to `/_security/oidc/prepare`. The response from {es} will contain 3 parameters: `redirect`, `state`, `nonce`. The custom web application would need to store the values for `state` @@ -605,9 +611,9 @@ POST /_security/oidc/prepare . Handle a subsequent response from the OP. After the user is successfully authenticated with the OpenID Connect Provider, they will be redirected back to the callback/redirect URI. Upon receiving this HTTP GET request, the custom web app will need to make an HTTP POST request to - `_security/oidc/authenticate`, again - authenticating as the `facilitator` user passing the URL of - the GET request it received as a parameter, along with the values for `nonce` and `state` it had - saved in the user's session previously. + `_security/oidc/authenticate`, again - authenticating as the `facilitator` user - passing the URL + where the user's browser was redirected to, as a parameter, along with the + values for `nonce` and `state` it had saved in the user's session previously. See <> for more details + [source,js] @@ -620,7 +626,7 @@ POST /_security/oidc/authenticate } ----------------------------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] +// 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 @@ -637,7 +643,7 @@ POST /_security/oidc/logout } -------------------------------------------------- // CONSOLE -// TEST[skip:These are properly tested in the OpenIDConnectIT suite] +// TEST[catch:bad_request] + If the realm is configured accordingly, this may result in a response with a `redirect` parameter indicating where the user needs to be redirected in the OP in order to complete the logout process. From 0f659df5c27340f502ae0e5f7ab273bfa37a4126 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Wed, 8 May 2019 13:17:29 +0300 Subject: [PATCH 06/16] Address feedback --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 2f3fe48d21cc4..74e0ac1f6990e 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -130,7 +130,7 @@ rp.client_id:: rp.response_type:: This is an identifier that controls which OpenID Connect authentication flow this RP supports and also - which flow this PR requests the OP should follow. Supported values are + which flow this RP requests the OP should follow. Supported values are - `code`, which means that the RP wants to use the Authorization Code flow. If your OP supports the Authorization Code flow, you should select this in favor of the Implicit Flow. - `id_token token` which means that the RP wants to use the Implicit flow and we also request an oAuth2 @@ -147,7 +147,7 @@ rp.redirect_uri:: typically be +$\{kibana-url}/api/security/v1/oidc+ where _$\{kibana-url}_ is the base URL for your {kib} instance op.authorization_endpoint:: - The URL for the Authorization Endpoint in the OpenID Connect Provider. This is where the user's browser + The URL for the Authorization Endpoint in the OP. This is where the user's browser will be redirected to start the authentication process. The value for this setting should be provided by your OpenID Connect Provider. @@ -384,7 +384,7 @@ NOTE: You cannot use {stack-ov}/mapping-roles.html#mapping-roles-file[role mappi to grant roles to users authenticating via OpenID Connect. This is an example of a simple role mapping that grants the `kibana_user` role -to any user who authenticates against the `oidc1` OpenID Conenct realm: +to any user who authenticates against the `oidc1` OpenID Connect realm: [source,js] -------------------------------------------------- @@ -461,7 +461,6 @@ claim as it was contained in the ID Token or in the User Info response. Note tha include all the https://openid.net/specs/openid-connect-core-1_0.html#IDToken[ID Token claims] that pertain to the authentication event, rather than the user themselves. - This behaviour can be disabled by adding `populate_user_metadata: false` as a setting in the oidc realm. From cff33b0df934b3ee8e0906c0c8b1d405ea90fffa Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Wed, 8 May 2019 13:17:47 +0300 Subject: [PATCH 07/16] fix doc tests --- .../security/oidc-prepare-authentication-api.asciidoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc b/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc index 7a86eb9713ae6..a6ce410be6ee6 100644 --- a/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc +++ b/x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc @@ -68,8 +68,8 @@ OpenID Connect Provider with all the parameters of the Authentication Request, a "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM" } -------------------------------------------------- -// TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/$body.state/] -// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/$body.nonce/] +// TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/\$\{body.state\}/] +// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/\$\{body.nonce\}/] The following example generates an authentication request for the OpenID Connect Realm `oidc1`, where the values for the state and the nonce have been generated by the client @@ -122,5 +122,5 @@ OpenID Connect Provider with all the parameters of the Authentication Request, a "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM" } -------------------------------------------------- -// TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/$body.state/] -// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/$body.nonce/] \ No newline at end of file +// TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/\$\{body.state\}/] +// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/\$\{body.nonce\}/] \ No newline at end of file From d3803cb1d4c67fab4f486183ed91a61de063495e Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Wed, 8 May 2019 13:51:22 +0300 Subject: [PATCH 08/16] Remove op.name config from docs test cluster --- x-pack/docs/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/docs/build.gradle b/x-pack/docs/build.gradle index 7358d750fe0ed..14d6805d5bf21 100644 --- a/x-pack/docs/build.gradle +++ b/x-pack/docs/build.gradle @@ -82,7 +82,6 @@ integTestCluster { setting 'xpack.security.authc.realms.file.file.order', '0' setting 'xpack.security.authc.realms.native.native.order', '1' setting 'xpack.security.authc.realms.oidc.oidc1.order', '2' - setting 'xpack.security.authc.realms.oidc.oidc1.op.name', 'c2id-implicit' setting 'xpack.security.authc.realms.oidc.oidc1.op.issuer', 'http://127.0.0.1:8080' setting 'xpack.security.authc.realms.oidc.oidc1.op.authorization_endpoint', "http://127.0.0.1:8080/c2id-login" setting 'xpack.security.authc.realms.oidc.oidc1.op.token_endpoint', "http://127.0.0.1:8080/c2id/token" From 09e86d3289896c6e7c3efc6a4d34d2f8d45f13a7 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Wed, 8 May 2019 20:34:01 +0300 Subject: [PATCH 09/16] Expect the correct exception for malformed tokens since we can't complete an authentication in order to get valid tokens in doc tests eitherway --- x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc | 2 +- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc b/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc index 0acc2b6675acd..cb8840ca53590 100644 --- a/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc +++ b/x-pack/docs/en/rest-api/security/oidc-logout-api.asciidoc @@ -39,7 +39,7 @@ POST /_security/oidc/logout } -------------------------------------------------- // CONSOLE -// TEST[catch:bad_request] +// TEST[catch:unauthorized] The following example output of the response contains the URI pointing to the End Session Endpoint of the OpenID Connect Provider with all the parameters of the Logout Request, as HTTP GET parameters diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 74e0ac1f6990e..3cc4cebc3e6b8 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -642,7 +642,7 @@ POST /_security/oidc/logout } -------------------------------------------------- // CONSOLE -// TEST[catch:bad_request] +// TEST[catch:unauthorized] + If the realm is configured accordingly, this may result in a response with a `redirect` parameter indicating where the user needs to be redirected in the OP in order to complete the logout process. From f4ae9fe951ba81828f33b75505ee1744641facae Mon Sep 17 00:00:00 2001 From: lcawl Date: Wed, 8 May 2019 11:02:31 -0700 Subject: [PATCH 10/16] [DOCS] Fixes links --- .../authentication/oidc-guide.asciidoc | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 3cc4cebc3e6b8..39d60a71c7389 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -86,8 +86,8 @@ the authentication chain for {es} This realm has a few mandatory settings, and a number of optional settings. The available settings are described in detail in the -<>, this guide will explore the most -common settings. +{ref}/security-settings.html#ref-oidc-settings[Security settings in {es}], this +guide will explore the most common settings. Create an OpenID Connect (the realm type is `oidc`) realm in your `elasticsearch.yml` file similar to what is shown below: @@ -242,9 +242,10 @@ The recommended steps for configuring OpenID Claims mapping are as follows: party. This process greatly varies by provider - some will allow for static configuration while others will support that the RP requests the scopes that correspond to the claims to be "released" on authentication time. See - <> on how to configure the scopes to - request. To ensure interoperability and minimize the errors, you should only - request scopes that the OP supports, and which you intend to map to {es} user properties. + {ref}/security-settings.html#ref-oidc-settings[`rp.requested_scopes`] on how + to configure the scopes to request. To ensure interoperability and minimize + the errors, you should only request scopes that the OP supports, and which you + intend to map to {es} user properties. . Configure the OpenID Connect realm in {es} to associate the {es} user properties (see <> below), to the name of the claims that your @@ -338,7 +339,7 @@ address such as `admin@staff.example.com.attacker.net`. It is important that you make sure your regular expressions are as precise as possible so that you do not inadvertently open an avenue for user impersonation attacks. -[[3rd-party-login]] +[[third-party-login]] ==== Third Party Initiated Single Sign On The Open ID Connect realm in {es} supports 3rd party initiated login as described in the @@ -516,7 +517,7 @@ for this Kibana instance. are designed to prevent the {kib} server from processing requests that originated from outside the {kib} application. In order to support OpenID Connect messages that originate from your -OP or a third party (see <<3rd-party-login>>, we need to explicitly _whitelist_ the +OP or a third party (see <>, we need to explicitly _whitelist_ the OpenID Connect authentication endpoint within {kib}, so that the {kib} server will not reject these external messages. @@ -591,7 +592,7 @@ authenticate a user with OpenID Connect: . Make an HTTP POST request to `_security/oidc/prepare`, authenticating as the `facilitator` user, using the name of the OpenID Connect realm in the {es} configuration in the request body. See the -<> for more details +{ref}/security-api-oidc-prepare-authentication.html[OIDC Prepare Authentication API] for more details + [source,js] -------------------------------------------------- @@ -613,7 +614,7 @@ POST /_security/oidc/prepare `_security/oidc/authenticate`, again - authenticating as the `facilitator` user - passing the URL where the user's browser was redirected to, as a parameter, along with the values for `nonce` and `state` it had saved in the user's session previously. - See <> for more details + See {ref}/security-api-oidc-authenticate.html[OIDC Authenticate API] for more details + [source,js] ----------------------------------------------------------------------- @@ -629,9 +630,9 @@ POST /_security/oidc/authenticate + 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 <> + 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 - <> passing the access token and refresh token as parameters, as seen below + {ref}/security-api-oidc-logout.html[OIDC Logout API] passing the access token and refresh token as parameters, as seen below + [source,js] -------------------------------------------------- From f92a01d77ef4aef369391a30aadba3f5c20bf0a5 Mon Sep 17 00:00:00 2001 From: lcawl Date: Wed, 8 May 2019 11:46:03 -0700 Subject: [PATCH 11/16] [DOCS] Fixes OpenID API section --- x-pack/docs/en/rest-api/security.asciidoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/docs/en/rest-api/security.asciidoc b/x-pack/docs/en/rest-api/security.asciidoc index c04bae90801ee..abad1e38d77fd 100644 --- a/x-pack/docs/en/rest-api/security.asciidoc +++ b/x-pack/docs/en/rest-api/security.asciidoc @@ -76,6 +76,8 @@ native realm: * <> * <> +[float] +[[security-openid-apis]] === OpenID Connect You can use the following APIs to authenticate users against an OpenID Connect @@ -110,7 +112,7 @@ include::security/get-users.asciidoc[] include::security/has-privileges.asciidoc[] include::security/invalidate-api-keys.asciidoc[] include::security/invalidate-tokens.asciidoc[] -include::security/ssl.asciidoc[] include::security/oidc-prepare-authentication-api.asciidoc[] include::security/oidc-authenticate-api.asciidoc[] include::security/oidc-logout-api.asciidoc[] +include::security/ssl.asciidoc[] From 99d35b98324487a1456a6f0f01ae88f8d2901a3a Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Sat, 11 May 2019 10:49:30 +0300 Subject: [PATCH 12/16] Update x-pack/docs/en/security/authentication/oidc-guide.asciidoc Co-Authored-By: Lisa Cawley --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 39d60a71c7389..fb02db4afecdd 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -1,7 +1,7 @@ [role="xpack"] [[oidc-guide]] -== Configuring Single Sign On to the {stack} using OpenID Connect +== Configuring single sign-on to the {stack} using OpenID Connect The Elastic Stack supports Single Sign On using OpenID Connect via {kib} using {es} as the backend service that holds most of the functionality. {kib} and {es} From 139a41c7a5e5a29b476080e1b69d491fa145d0d7 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Sat, 11 May 2019 10:51:23 +0300 Subject: [PATCH 13/16] Update x-pack/docs/en/security/authentication/oidc-guide.asciidoc Co-Authored-By: Lisa Cawley --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index fb02db4afecdd..ee60909b8a30d 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -3,7 +3,7 @@ == Configuring single sign-on to the {stack} using OpenID Connect -The Elastic Stack supports Single Sign On using OpenID Connect via {kib} using +The Elastic Stack supports single sign-on (SSO) using OpenID Connect via {kib} using {es} as the backend service that holds most of the functionality. {kib} and {es} together represent an OpenID Connect Relying Party (RP) that supports the Authorization Code Flow and the Implicit Flow as these are defined in the OpenID Connect specification. From 107ef4677d96a611ad38a0f9425ff22c0f66a1a2 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Sat, 11 May 2019 10:52:04 +0300 Subject: [PATCH 14/16] Update x-pack/docs/en/security/authentication/oidc-guide.asciidoc Co-Authored-By: Lisa Cawley --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index ee60909b8a30d..2e79fa7f18bcc 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -8,7 +8,7 @@ The Elastic Stack supports single sign-on (SSO) using OpenID Connect via {kib} u together represent an OpenID Connect Relying Party (RP) that supports the Authorization Code Flow and the Implicit Flow as these are defined in the OpenID Connect specification. -This guide assumes that you have an OpenID Connect Provider that you use and where the +This guide assumes that you have an OpenID Connect Provider where the Elastic Stack Relying Party will be registered. NOTE: The OpenID Connect realm support in {kib} is designed with the expectation that it From 0ce4cd9d56b3ac9e9408eca7f1c6cfb8595a2ab2 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Thu, 16 May 2019 19:21:16 +0300 Subject: [PATCH 15/16] Apply suggestions from code review Co-Authored-By: Lisa Cawley --- .../authentication/oidc-guide.asciidoc | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 2e79fa7f18bcc..425cb08f6bc46 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -32,24 +32,24 @@ also allow for the manual registration of an RP as a client, via a user interfac via the consumption of a metadata document. The process for registering the Elastic Stack RP will be different from OP to OP and following -the provider's relevant documentation is prudent. The most usual piece of information for the -RP that you need to provide for registration are the following: +the provider's relevant documentation is prudent. The information for the +RP that you commonly need to provide for registration are the following: - `Relying Party Name`: An arbitrary identifier for the relying party. Neither the specification nor the Elastic Stack implementation impose any constraints on this value. - `Redirect URI`: This is the URI where the OP will redirect the user's browser after authentication. The appropriate value for this will depend on your setup and whether or not {kib} sits behind a proxy or -load balancer, but it will typically be +$\{kibana-url}/api/security/v1/oidc+ where _$\{kibana-url}_ +load balancer. It will typically be +$\{kibana-url}/api/security/v1/oidc+ where _$\{kibana-url}_ is the base URL for your {kib} instance. You might also see this called `Callback URI`. -At the end of the registration process, the OP will assign aClient Identifier and a Client Secret for the RP ({stack}) to use. +At the end of the registration process, the OP will assign a Client Identifier and a Client Secret for the RP ({stack}) to use. Note these two values as they will be used in the {es} configuration. [[oidc-guide-authentication]] === Configure {es} for OpenID Connect authentication The following is a summary of the configuration steps required in order to enable authentication -using OpenID Connect in {es} +using OpenID Connect in {es}: . <> . <> @@ -82,11 +82,11 @@ xpack.security.authc.token.enabled: true ==== Create an OpenID Connect realm OpenID Connect based authentication is enabled by configuring the appropriate realm within -the authentication chain for {es} +the authentication chain for {es}. This realm has a few mandatory settings, and a number of optional settings. The available settings are described in detail in the -{ref}/security-settings.html#ref-oidc-settings[Security settings in {es}], this +{ref}/security-settings.html#ref-oidc-settings[Security settings in {es}]. This guide will explore the most common settings. Create an OpenID Connect (the realm type is `oidc`) realm in your `elasticsearch.yml` file @@ -132,7 +132,7 @@ rp.response_type:: This is an identifier that controls which OpenID Connect authentication flow this RP supports and also which flow this RP requests the OP should follow. Supported values are - `code`, which means that the RP wants to use the Authorization Code flow. If your OP supports the - Authorization Code flow, you should select this in favor of the Implicit Flow. + Authorization Code flow, you should select this instead of the Implicit Flow. - `id_token token` which means that the RP wants to use the Implicit flow and we also request an oAuth2 access token from the OP, that we can potentially use for follow up requests ( UserInfo ). This should be selected if the OP offers a UserInfo endpoint in its configuration, or if you know that @@ -206,14 +206,14 @@ for the authenticated user. Simply put, a claim is a name/value pair that contai the user. Related to claims, we also have the notion of OpenID Connect Scopes. Scopes are identifiers that are used to request access to specific lists of claims. The standard defines a set of scope identifiers that can be requested. The only mandatory one is `openid`, while commonly used ones are -`profile` ( requesting access to the `name`,`family_name`,`given_name`,`middle_name`,`nickname`, -`preferred_username`,`profile`,`picture`,`website`,`gender`,`birthdate`,`zoneinfo`,`locale`,`updated_at` claims), -and `email` (requesting access to the `email` and `email_verified` claims). The process is that -the RP requests specific scopes during the authentication request, and if the OP Privacy Policy +`profile` and `email`. The `profile` scope requests access to the `name`,`family_name`,`given_name`,`middle_name`,`nickname`, +`preferred_username`,`profile`,`picture`,`website`,`gender`,`birthdate`,`zoneinfo`,`locale`, and `updated_at` claims. +The `email` scope requests access to the `email` and `email_verified` claims. The process is that +the RP requests specific scopes during the authentication request. If the OP Privacy Policy allows it and the authenticating user consents to it, the related claims are returned to the -RP, either in the ID Token, or as a UserInfo response. +RP (either in the ID Token or as a UserInfo response). -The list of the supported claims will vary depending on the OP you are using, but one should expect +The list of the supported claims will vary depending on the OP you are using, but you can expect the https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[Standard Claims] to be largely supported. @@ -228,8 +228,8 @@ logs, and can also be used to create <> rules. The recommended steps for configuring OpenID Claims mapping are as follows: . Consult your OP configuration to see what claims it might support. Note that - the list provided in the OPs metadata, or in the configuration page of the OP - is a list of potentially supported claims, but for privacy reasons it might + the list provided in the OP's metadata or in the configuration page of the OP + is a list of potentially supported claims. However, for privacy reasons it might not be a complete one, or not all supported claims will be available for all authenticated users. @@ -239,10 +239,10 @@ The recommended steps for configuring OpenID Claims mapping are as follows: is required. . Configure your OP to "release" those claims to your {stack} Relying - party. This process greatly varies by provider - some will allow for static + party. This process greatly varies by provider. You can use a static configuration while others will support that the RP requests the scopes that correspond to the claims to be "released" on authentication time. See - {ref}/security-settings.html#ref-oidc-settings[`rp.requested_scopes`] on how + {ref}/security-settings.html#ref-oidc-settings[`rp.requested_scopes`] for details about how to configure the scopes to request. To ensure interoperability and minimize the errors, you should only request scopes that the OP supports, and which you intend to map to {es} user properties. @@ -284,7 +284,7 @@ NOTE: If the principal property fails to be mapped from a claim, the authenticat groups:: _(Recommended)_ If you wish to use your OP's concept of groups or roles as the basis for a user's {es} privileges, you should map them with this property. - The `groups` are passed directly to your <> + The `groups` are passed directly to your <>. name:: _(Optional)_ The user's full name. mail:: _(Optional)_ The user's email address. @@ -321,7 +321,7 @@ xpack.security.authc.realms.oidc.oidc1: In this case, the user's `principal` is mapped from the `email_verified` claim, but a regular expression is applied to the value before it is assigned to the user. -If the regular expression matches, then the result of the first group is used as +If the regular expression matches, then the result of the first group is used as the effective value. If the regular expression does not match then the claim mapping fails. @@ -340,10 +340,10 @@ you make sure your regular expressions are as precise as possible so that you do not inadvertently open an avenue for user impersonation attacks. [[third-party-login]] -==== Third Party Initiated Single Sign On +==== Third party initiated single sign-on The Open ID Connect realm in {es} supports 3rd party initiated login as described in the -https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin[relevant specification] +https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin[relevant specification]. This allows the OP itself or another, third party other than the RP, to initiate the authentication process while requesting the OP to be used for the authentication. Please note that the Elastic @@ -361,12 +361,12 @@ In this process, the OpenID Connect RP (the Elastic Stack in this case) will red browser to predefined URL of the OP after successfully completing a local logout. The OP can then logout the user also, depending on the configuration, and should finally redirect the user back to the RP. The `op.endsession_endpoint` in the realm configuration determines the URL in the OP that the browser -will be redirected and the `rp.post_logout_redirect_uri` setting determines the URL to redirect back -the user after OP logs them out. +will be redirected to. The `rp.post_logout_redirect_uri` setting determines the URL to redirect +the user back to after the OP logs them out. When configuring `rp.post_logout_redirect_uri`, care should be taken to not point this to a URL that will trigger re-authentication of the user. For instance, when using OpenID Connect to support -Single Sign On to {kib}, this could be set to +$\{kibana-url}/logged_out+ that will show a user +single sign-on to {kib}, this could be set to +$\{kibana-url}/logged_out+, which will show a user- friendly message to the user. [[oidc-role-mapping]] @@ -455,9 +455,9 @@ In this case, you perform the following steps: === User metadata By default users who authenticate via OpenID Connect will have some additional metadata -fields. These will include every OpenID Claim that is provided in the authentication response -(regardless of whether it is mapped to an {es} user property), will be added -as the metadata field `oidc(claim_name)` where "claim_name" is the name of the +fields. These fields will include every OpenID Claim that is provided in the authentication response +(regardless of whether it is mapped to an {es} user property). For example, +in the metadata field `oidc(claim_name)`, "claim_name" is the name of the claim as it was contained in the ID Token or in the User Info response. Note that these will include all the https://openid.net/specs/openid-connect-core-1_0.html#IDToken[ID Token claims] that pertain to the authentication event, rather than the user themselves. @@ -494,11 +494,11 @@ server.xsrf.whitelist: [/api/security/v1/oidc] The configuration values used in the example above are: `xpack.security.authProviders`:: -Set this to `[ oidc ]` to instruct {kib} to use OpenID Connect Single Sign On as the -authentication method. This instructs kibana to attempt and initiate an SSO flow +Set this to `[ oidc ]` to instruct {kib} to use OpenID Connect single sign-on as the +authentication method. This instructs Kibana to attempt to initiate an SSO flow everytime a user attempts to access a URL in Kibana, if the user is not already -authenticated. If you wish to allow users to login with a username and password -also, then you'd need to enable the `basic` authProvider too by setting +authenticated. If you also want to allow users to login with a username and password, +you must enable the `basic` authProvider too. For example: [source, yaml] ------------------------------------------------------------ @@ -513,8 +513,8 @@ The name of the OpenID Connect realm in {es} that should handle authentication for this Kibana instance. `server.xsrf.whitelist`:: -{kib} has in-built protection against _Cross Site Request Forgery_ attacks which -are designed to prevent the {kib} server from processing requests that +{kib} has in-built protection against _Cross Site Request Forgery_ attacks, which +is designed to prevent the {kib} server from processing requests that originated from outside the {kib} application. In order to support OpenID Connect messages that originate from your OP or a third party (see <>, we need to explicitly _whitelist_ the @@ -529,15 +529,15 @@ such, most of the parts of the guide above make the assumption that {kib} is use This section describes how a custom web application could use the relevant OpenID Connect REST APIs in order to authenticate the users to {es}, with OpenID Connect. -Single Sign On realms such as OpenID Connect and SAML make use of the Token Service in +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 to be used as credentials for subsequent calls to {es} and a -refresh token allowing to get new {es} access tokens for the user once the current one +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. NOTE: The {es} Token Service can be seen as a minimal oAuth2 authorization server and the access token and refresh token mentioned above are tokens that pertain -_only_ to this authorization server, are generated and consumed _only_ by {es} +_only_ to this authorization server. They are generated and consumed _only_ by {es} and are in no way related to the tokens ( access token and ID Token ) that the OpenID Connect Provider issues. @@ -549,7 +549,7 @@ client with the OpenID Connect Provider. Note that when registering the ==== OpenID Connect Realm -As before, an OpenID Connect realm needs to be created and configured accordingly +An OpenID Connect realm needs to be created and configured accordingly in {es}. See <> ==== Service Account user for accessing the APIs @@ -632,7 +632,7 @@ Elasticsearch will validate this and if all is correct will respond with an acce 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, as seen below + {ref}/security-api-oidc-logout.html[OIDC Logout API] passing the access token and refresh token as parameters. For example: + [source,js] -------------------------------------------------- From 9947dc40a5f609b237c593f53b4512277febeec4 Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Mon, 20 May 2019 10:52:43 +0300 Subject: [PATCH 16/16] Address feedback, note that implicit flow is not supported by kibana yet --- x-pack/docs/en/security/authentication/oidc-guide.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc index 425cb08f6bc46..df5ce11c63c14 100644 --- a/x-pack/docs/en/security/authentication/oidc-guide.asciidoc +++ b/x-pack/docs/en/security/authentication/oidc-guide.asciidoc @@ -6,7 +6,7 @@ The Elastic Stack supports single sign-on (SSO) using OpenID Connect via {kib} using {es} as the backend service that holds most of the functionality. {kib} and {es} together represent an OpenID Connect Relying Party (RP) that supports the Authorization -Code Flow and the Implicit Flow as these are defined in the OpenID Connect specification. +Code Flow as this is defined in the OpenID Connect specification. This guide assumes that you have an OpenID Connect Provider where the Elastic Stack Relying Party will be registered. @@ -171,7 +171,7 @@ op.jwkset_path:: Provider uses for signing tokens and claims responses. The path is resolved relative to the {es} config directory. {es} will automatically monitor this file for changes and will reload the configuration whenever - it is updated. The value for this setting should be provided by your OpenID Connect Provider. + it is updated. Your OpenID Connect Provider should provide you with this file. claims.principal:: See <>. claims.groups:: See <>.