From 8a0430a61461948241ec95214c5a3492530fd180 Mon Sep 17 00:00:00 2001 From: watucker Date: Wed, 8 Jul 2020 18:45:26 +0100 Subject: [PATCH 1/6] Added idp registration document + images Document explains use-cases and procedures for different levels of IDP registration. --- idp-registration.md | 330 ++++++++++++++++++ .../images/github-oauth-application-setup.png | Bin 0 -> 38585 bytes media/images/github-oauth-client-details.png | Bin 0 -> 8082 bytes .../github-oauth-register-an-application.png | Bin 0 -> 19650 bytes media/images/idp-proxy-architecture.png | Bin 0 -> 31804 bytes 5 files changed, 330 insertions(+) create mode 100644 idp-registration.md create mode 100644 media/images/github-oauth-application-setup.png create mode 100644 media/images/github-oauth-client-details.png create mode 100644 media/images/github-oauth-register-an-application.png create mode 100644 media/images/idp-proxy-architecture.png diff --git a/idp-registration.md b/idp-registration.md new file mode 100644 index 0000000..aee9f2b --- /dev/null +++ b/idp-registration.md @@ -0,0 +1,330 @@ +# Identity Provider Registration + +## Introduction + +This guide details the process for bootstrapping different layers of the ESGf identity management infrastructure. Specifically, the registration of client applications (*Relying Parties*) with identity management services (*Identity Providers*). We are using OpenID Connect on top of the OAuth 2 protocol to facilitate the sharing of identities between applications. + +Keycloak, an open source and highly customisable identity management server, can act as both *Relying Party* and an *Identity Provider*. This is the technology we are using for the main components of the identity management system, the **IDP Proxy** and the organisation-specific **Local IDP** servers. + +The diagram below shows the various components in this architecture. The connections between components are our use-cases: + + + +## Actors + +- **Relying Party (RP):** + An OAuth 2.0 Client application that requires user authentication and claims from an Identity Provider. Relying Parties must register themselves with an Identity Provider to allow this interaction. +- **Identity Provider (IDP)** + This is a trusted source of authority on user identity which communicates with a Relying Party using the OAuth 2.0 protocol. +- **Keycloak:** + Keycloak is an identity management server written in Java. Its documentation can be found **here**. +- **Local IDP:** + This is a Keycloak server installed on a node at an ESGF site and acting as an Identity Provider. It would be appropriately branded and provide login and registration for users at that site. +- **IDP Proxy:** + This is a Keycloak server acting as the central identity management service for ESGF. While it facilitates login for ESGF users, it does not allow registration. Instead, acts as a proxy to Local IDPs (hence "IDP Proxy") which provide it with user identities. This gives it access to all users in the federation, allowing it to be the Identity Provider for all ESGF applications. +- **Commercial IDP:** + An Identity Provider not managed by ESGF but which could be hooked up to the IDP Proxy to provide additional login options for "homeless" users. e.g. GitHub, Google Plus, etc. +- **ESGF Application:** + An application, typically a web application (e.g. COG), which may utilise user account information provided by the OpenID Connect protocol. This would be facilitated by acting as Relying Party to the IDP Proxy using some kind of OpenID Connect authentication library. +- **IDP Administrator:** + A person with access to the administration backend of an Identity Provider. For example, somebody with access to the admin console of a Keycloak instance. This may also be the owner or an administrator of a GitHub organisation. +- **RP Administrator:** + A person with access to the administration backend of a Relying Party. This could be the manager of a web application or the administrator of a Keycloak server that is behaving as a Relying Party. +- **Realm:** + In Keycloak, a realm manages a set of users, credentials, roles, and groups. All interactions with a Keycloak server happen within the context of a realm. +- **Client:** + In Keycloak, clients are entities that can request Keycloak to authenticate a user. All OAuth 2.0 flows happen via a client configured on an Identity Provider's server. +- **Keycloak API:** + The Keycloak Admin REST API provides endpoints to manipulate a Keycloak realm. We are using it to automate the process of client registration. +- **Keycloak API User:** + This is any Keycloak user with authority to use the Keycloak Admin REST API for a given realm. +- **Bearer Token:** + This is a token included in an HTTP Authorization header that authorizes access to a particular resource or set of resources without the sender needing to prove their identity. + +## Use cases + +This document will detail that procedure for the following use-cases: + +1. Registering the ESGF IDP Proxy with an organisation’s Local IDP + + **Relying Party**: Local IDP (Keycloak) + **Identity Provider**: IDP Proxy (Keycloak) + +2. Registering the ESGF IDP proxy with a Commercial IDP + + **Relying Party**: IDP Proxy (Keycloak) + **Identity Provider**: Commercial IDP (e.g. GitHub) + +3. Registering an ESGF application with the ESGF IDP Proxy + + **Relying Party**: An ESGF application (e.g. COG) + **Identity Provider**: IDP Proxy (Keycloak) + +## Setting up access to a Keycloak server’s REST API + +*This section assumes you have access to a **Keycloak** server with an accessible **realm** (see **Installing Keycloak**)* + +Before being able to use the API for a Keycloak installation, some setup must be performed by an administrator of that server. + +1. The Keycloak administrator should create a dedicated *API user*. This account should have permission to access the *Keycloak API* for `` on the server. + +2. Access to this *API user* should be granted to the person who wishes to use the API to, for example, register a *Relying Party* (e.g. an *RP administrator*). + + - Keycloak allows you to send a password reset email for a user via the admin interface. This makes it easy to grant accounts to other people. + +3. With the credentials of this *API user*, we can now a request an API access token (*Bearer Token*): + + *Request* + ```http + Endpoint: https://keycloak.example.com/auth/realms//protocol/openid-connect/token + Method: POST + Content-Type: application/x-www-form-urlencoded + + Data: + client_id = admin-cli + grant_type = password + username = + password = + ``` + + *JSON Response* + ```json + { + "access_token": "", + "expires_in": 60, + "refresh_expires_in": 1800, + "refresh_token": "", + "token_type": "bearer", + "not-before-policy": 0, + "session_state": "", + "scope": "profile email" + } + ``` + +4. Save the `` from the response. This is our *Bearer Token*. It can be used until the expiry time (60 seconds, in this case) has passed. + +The *Bearer Token* can now be used to access the Keycloak admin API to register clients or configure IDPs. + +## Case 1: Registering the IDP Proxy with an organisation’s Local IDP + +In this use case, the **Local IDP** is acting as an *Identity Provider* and the **IDP Proxy** is a *Relying Party*. + +The first step is to establish access to the *Keycloak API*: + +1. Fetch a *Bearer Token* from the *Local IDP* for the relevant *Realm*. (see ***Setting up access to a Keycloak IDP’s REST API***) + +Now the *Keycloak API* for the *Local IDP*'s `` can be queried: + +2. Register a new *Client*: + + *Request* + ```http + Endpoint: https://localidp.example.com/auth/realms//clients + Authorization: Bearer + Method: POST + Content-Type: application/json + + JSON: + { + "clientId": "" + } + ``` + + The response will be empty but a new *Client* will have been created on `` + +3. Retrieve the `` using the ``: + + *Request* + ```http + Endpoint: https://localidp.example.com/auth/realms//clients + Authorization: Bearer + Method: GET + + Query: + clientId = + ``` + + *JSON Response* + ```json + [ + { + "id": "", + "clientId": "", + ... + } + ] + ``` + +4. Using ``, retrieve the ``: + + *Request* + ```http + Endpoint: https://localidp.example.com/auth/realms//clients//client-secret + Authorization: Bearer + Method: GET + ``` + + *JSON Response* + ```json + { + "type": "secret", + "value": "" + } + ``` + +Now that the *Client* details have been retrieved, the last stage is to set up the new IDP in Keycloak based on the acquired credentials. This will require querying the *IDP Proxy's* *Keycloak API*. + +5. Fetch a *Bearer Token* from the *IDP Proxy* for the relevant *Realm*. (see ***Setting up access to a Keycloak IDP’s REST API***) + +6. Create a new Keycloak Identity Provider on `` with the `` and ``: + + *Request* + ```http + Endpoint: https://centralidp.example.com/auth/realms//identity-provider/instances + Authorization: Bearer + Method: POST + Content-Type: application/json + + JSON: + { + "alias": "", + "config": + { + "authorizationUrl": "https://localidp.example.com/auth/realms//protocol/openid-connect/auth", + "tokenUrl": "https://localidp.example.com/auth/realms//protocol/openid-connect/token", + "clientAuthentication": "jwt", + "clientId": "", + "clientSecret": "" + } + } + ``` + + The response will be empty but a new *Identity Provider* will have been created on `` + +## Case 2: Registering the ESGF IDP proxy with a Commercial IDP + +In this use case, a **Commercial IDP** is acting as an *Identity Provider* and the **IDP Proxy** is a *Relying Party*. + +The first part of this process, the registration of our client, will differ depending on which provider you are using. Though, most will provide instructions. + +In this example, we are using GitHub as the *Identity Provider*: + +1. On your GitHub organisation's settings page, under "Developer settings", click the "OAuth Apps" button. This will let you register a new OAuth application, which is what we want. + + + +2. The application must be configured with a name, a homepage URL and an authorization callback URL. + + + + The only important thing here is the callback URL, since this will be where users are redirected to once they have authenticated with their GitHub credentials. In our case, the authorization callback URL will be: + + `https://centralidp.example.com/auth/realms//broker/github/endpoint` + +3. Selecting the application, you should be able to see its ID and secret: + + + +Now that the *Client* has been set up and we have the ID and secret, the last stage is to configure a new IDP in Keycloak with these client details. This will require querying the *IDP Proxy's* *Keycloak API*: + +4. Fetch a *Bearer Token* from the *IDP Proxy* for the relevant *Realm*. (see ***Setting up access to a Keycloak IDP’s REST API***) + +5. Create a new Keycloak Identity Provider on `` with the `` and ``: + + *Request* + ```http + Endpoint: https://centralidp.example.com/auth/realms//identity-provider/instances + Authorization: Bearer + Method: POST + Content-Type: application/json + + JSON: + { + "alias": "", + "config": + { + "authorizationUrl": "https://localidp.example.com/auth/realms//protocol/openid-connect/auth", + "tokenUrl": "https://localidp.example.com/auth/realms//protocol/openid-connect/token", + "clientAuthentication": "jwt", + "clientId": "", + "clientSecret": "" + } + } + ``` + + The response will be empty but a new *Identity Provider* will have been created on `` + +## Case 3: Registering an ESGF application with the ESGF IDP proxy + +In this use case, the **IDP Proxy** is acting as an *Identity Provider* and an **ESGF Application** is acting as a *Relying Party*. + +This case is similar to registering the IDP Proxy with a Local IDP, but in this case we are registering with the IDP Proxy. + +The first step is to establish access to the *Keycloak API*: + +1. Fetch a *Bearer Token* from the **IDP Proxy** for the relevant *Realm*. (see ***Setting up access to a Keycloak IDP’s REST API***) + +Now the *Keycloak API* for the **IDP Proxy**'s `` can be queried: + +2. Register a new *Client*: + + *Request* + ```http + Endpoint: https://centralidp.example.com/auth/realms//clients + Authorization: Bearer + Method: POST + Content-Type: application/json + + JSON: + { + "clientId": "" + } + ``` + + The response will be empty but a new *Client* will have been created on `` + +3. Retrieve the `` using the ``: + + *Request* + ```http + Endpoint: https://centralidp.example.com/auth/realms//clients + Authorization: Bearer + Method: GET + + Query: + clientId = + ``` + + *JSON Response* + ```json + [ + { + "id": "", + "clientId": "", + ... + } + ] + ``` + +4. Using ``, retrieve the ``: + + *Request* + ```http + Endpoint: https://centralidp.example.com/auth/realms//clients//client-secret + Authorization: Bearer + Method: GET + ``` + + *JSON Response* + ```json + { + "type": "secret", + "value": "" + } + ``` + +This completes the registration of the ESGF Application's client. Next, the application must be configured to use the **IDP Proxy** as an *Identity Provider*. This configuration will look different depending on what kind of OIDC support you are using. + +In the following steps, we will assume that we are configuring a Django web application using the `mozilla-django-oidc` authentication backen. Since this configuration requires direct access to the web application's deployment, it can obviously only be done by someone with privileges access to the deployment (i.e. the *RP Administrator*). + +5. diff --git a/media/images/github-oauth-application-setup.png b/media/images/github-oauth-application-setup.png new file mode 100644 index 0000000000000000000000000000000000000000..9faf17c7b795c4274c339e52bcf0f0095a5469a7 GIT binary patch literal 38585 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Òi6+Vbi4{YPgZE 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 KHLTVYj{X;RQ#54& literal 0 HcmV?d00001 diff --git a/media/images/github-oauth-client-details.png b/media/images/github-oauth-client-details.png new file mode 100644 index 0000000000000000000000000000000000000000..35f88b3e6a33dbaff2b2a0d89a4f237eb13d0ab2 GIT binary patch literal 8082 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 KTr187CjJjQ_(nhg literal 0 HcmV?d00001 diff --git a/media/images/idp-proxy-architecture.png b/media/images/idp-proxy-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..62e185026eeadb9ee8a648f37f4be5ba3eb9bb3f GIT binary patch literal 31804 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 literal 0 HcmV?d00001 From 7d64f5feec0533a3c567c966940598f0a88fa21d Mon Sep 17 00:00:00 2001 From: watucker Date: Thu, 9 Jul 2020 16:16:22 +0100 Subject: [PATCH 2/6] Wording changes for IDP doc --- idp-registration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/idp-registration.md b/idp-registration.md index aee9f2b..0676b62 100644 --- a/idp-registration.md +++ b/idp-registration.md @@ -21,7 +21,7 @@ The diagram below shows the various components in this architecture. The connect - **Local IDP:** This is a Keycloak server installed on a node at an ESGF site and acting as an Identity Provider. It would be appropriately branded and provide login and registration for users at that site. - **IDP Proxy:** - This is a Keycloak server acting as the central identity management service for ESGF. While it facilitates login for ESGF users, it does not allow registration. Instead, acts as a proxy to Local IDPs (hence "IDP Proxy") which provide it with user identities. This gives it access to all users in the federation, allowing it to be the Identity Provider for all ESGF applications. + This is a Keycloak server acting as the central identity management service for ESGF. While it facilitates login for ESGF users, it does not allow registration. Instead acting as proxy to multiple Local IDPs (hence "IDP Proxy") which provide it with user identities. This gives it access to all users in the federation, allowing it to be the Identity Provider for all ESGF applications. - **Commercial IDP:** An Identity Provider not managed by ESGF but which could be hooked up to the IDP Proxy to provide additional login options for "homeless" users. e.g. GitHub, Google Plus, etc. - **ESGF Application:** @@ -43,7 +43,7 @@ The diagram below shows the various components in this architecture. The connect ## Use cases -This document will detail that procedure for the following use-cases: +This document will detail the procedure for the following use-cases: 1. Registering the ESGF IDP Proxy with an organisation’s Local IDP @@ -325,6 +325,6 @@ Now the *Keycloak API* for the **IDP Proxy**'s `` can be queried: This completes the registration of the ESGF Application's client. Next, the application must be configured to use the **IDP Proxy** as an *Identity Provider*. This configuration will look different depending on what kind of OIDC support you are using. -In the following steps, we will assume that we are configuring a Django web application using the `mozilla-django-oidc` authentication backen. Since this configuration requires direct access to the web application's deployment, it can obviously only be done by someone with privileges access to the deployment (i.e. the *RP Administrator*). +As an example, we will assume that we are configuring a Django web application using the `mozilla-django-oidc` authentication backen. Since this configuration requires direct access to the web application's deployment, it can obviously only be done by someone with privileges access to the deployment (i.e. the *RP Administrator*). -5. +The steps for this are detailed in the _mozilla-django-oidc documentation_. From 00e42601f460d545b5949be6eca2be9fa610e28f Mon Sep 17 00:00:00 2001 From: watucker Date: Thu, 9 Jul 2020 16:50:24 +0100 Subject: [PATCH 3/6] Update idp-registration.md --- idp-registration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idp-registration.md b/idp-registration.md index 0676b62..184ec0f 100644 --- a/idp-registration.md +++ b/idp-registration.md @@ -2,9 +2,9 @@ ## Introduction -This guide details the process for bootstrapping different layers of the ESGf identity management infrastructure. Specifically, the registration of client applications (*Relying Parties*) with identity management services (*Identity Providers*). We are using OpenID Connect on top of the OAuth 2 protocol to facilitate the sharing of identities between applications. +This guide details the process for bootstrapping different layers of the ESGf identity management infrastructure. Specifically, the registration of client applications (*Relying Parties*) with identity management services (*Identity Providers*). We are using [OpenID Connect](https://openid.net/connect/) on top of the OAuth 2 protocol to facilitate the sharing of identities between applications. -Keycloak, an open source and highly customisable identity management server, can act as both *Relying Party* and an *Identity Provider*. This is the technology we are using for the main components of the identity management system, the **IDP Proxy** and the organisation-specific **Local IDP** servers. +[Keycloak](https://www.keycloak.org/documentation), an open source and highly customisable identity management server, can act as both *Relying Party* and an *Identity Provider*. This is the technology we are using for the main components of the identity management system, the **IDP Proxy** and the organisation-specific **Local IDP** servers. The diagram below shows the various components in this architecture. The connections between components are our use-cases: @@ -327,4 +327,4 @@ This completes the registration of the ESGF Application's client. Next, the appl As an example, we will assume that we are configuring a Django web application using the `mozilla-django-oidc` authentication backen. Since this configuration requires direct access to the web application's deployment, it can obviously only be done by someone with privileges access to the deployment (i.e. the *RP Administrator*). -The steps for this are detailed in the _mozilla-django-oidc documentation_. +The steps for this are detailed in the [mozilla-django-oidc documentation](https://mozilla-django-oidc.readthedocs.io/en/stable/installation.html). From e970d0eadb99e6be17f3711fe736b3d10542e42f Mon Sep 17 00:00:00 2001 From: watucker Date: Thu, 9 Jul 2020 16:58:06 +0100 Subject: [PATCH 4/6] Update idp-registration.md --- idp-registration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idp-registration.md b/idp-registration.md index 184ec0f..7b066d8 100644 --- a/idp-registration.md +++ b/idp-registration.md @@ -62,7 +62,7 @@ This document will detail the procedure for the following use-cases: ## Setting up access to a Keycloak server’s REST API -*This section assumes you have access to a **Keycloak** server with an accessible **realm** (see **Installing Keycloak**)* +*This section assumes you have access to a **Keycloak** server with an accessible **realm*** Before being able to use the API for a Keycloak installation, some setup must be performed by an administrator of that server. @@ -111,7 +111,7 @@ In this use case, the **Local IDP** is acting as an *Identity Provider* and the The first step is to establish access to the *Keycloak API*: -1. Fetch a *Bearer Token* from the *Local IDP* for the relevant *Realm*. (see ***Setting up access to a Keycloak IDP’s REST API***) +1. Fetch a *Bearer Token* from the *Local IDP* for the relevant *Realm*. (see [Setting up access to a Keycloak IDP’s REST API](#setting-up-access-to-a-keycloak-servers-rest-api)) Now the *Keycloak API* for the *Local IDP*'s `` can be queried: @@ -174,7 +174,7 @@ Now the *Keycloak API* for the *Local IDP*'s `` can be queried: Now that the *Client* details have been retrieved, the last stage is to set up the new IDP in Keycloak based on the acquired credentials. This will require querying the *IDP Proxy's* *Keycloak API*. -5. Fetch a *Bearer Token* from the *IDP Proxy* for the relevant *Realm*. (see ***Setting up access to a Keycloak IDP’s REST API***) +5. Fetch a *Bearer Token* from the *IDP Proxy* for the relevant *Realm*. (see [Setting up access to a Keycloak IDP’s REST API](#setting-up-access-to-a-keycloak-servers-rest-api)) 6. Create a new Keycloak Identity Provider on `` with the `` and ``: From adc84c6f12b0dadd888a0127d498a64aa322c0d9 Mon Sep 17 00:00:00 2001 From: watucker Date: Fri, 4 Sep 2020 17:59:03 +0100 Subject: [PATCH 5/6] Fixed missing link --- idp-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idp-registration.md b/idp-registration.md index 7b066d8..c40162e 100644 --- a/idp-registration.md +++ b/idp-registration.md @@ -17,7 +17,7 @@ The diagram below shows the various components in this architecture. The connect - **Identity Provider (IDP)** This is a trusted source of authority on user identity which communicates with a Relying Party using the OAuth 2.0 protocol. - **Keycloak:** - Keycloak is an identity management server written in Java. Its documentation can be found **here**. + Keycloak is an identity management server written in Java. Its documentation can be found [here](https://www.keycloak.org/documentation). - **Local IDP:** This is a Keycloak server installed on a node at an ESGF site and acting as an Identity Provider. It would be appropriately branded and provide login and registration for users at that site. - **IDP Proxy:** From 56e6d2e04830df5d884bbf8625369f9c9f420d2d Mon Sep 17 00:00:00 2001 From: watucker Date: Fri, 4 Sep 2020 17:59:18 +0100 Subject: [PATCH 6/6] Added IDP user accounts page --- idp_user_accounts.md | 103 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 idp_user_accounts.md diff --git a/idp_user_accounts.md b/idp_user_accounts.md new file mode 100644 index 0000000..38c731c --- /dev/null +++ b/idp_user_accounts.md @@ -0,0 +1,103 @@ +# IDP Proxy User Sign In and Registration + +The ESGF IDP Proxy functions as a general identity provider for all ESGF sites. Though it does not directly provide password-based login or account registation, it does act as a gateway to other identity providers that users can sign up to and login with. + +This document will outline the user management facilities provided by Keycloak, as well as some of the common use-cases that we are supporting. + +### Actors + +- **Keycloak:** + Keycloak is an identity management server written in Java. Its documentation can be found [here](https://www.keycloak.org/documentation). +- **Relying Party (RP):** + An OAuth 2.0 Client application that requires user authentication and claims from an Identity Provider. Relying Parties must register themselves with an Identity Provider to allow this interaction. +- **Identity Provider (IDP)** + This is a trusted source of authority on user identity which communicates with a Relying Party using the OAuth 2.0 protocol. +- **IDP Proxy:** + This is a Keycloak server acting as the central identity management service for ESGF. While it facilitates login for ESGF users, it does not allow registration. Instead acting as proxy to multiple Local IDPs (hence "IDP Proxy") which provide it with user identities. This gives it access to all users in the federation, allowing it to be the Identity Provider for all ESGF applications. +- **ESGF site-specific IDP:** + This is a Keycloak server installed on a node at an ESGF site and acting as an Identity Provider. It would be appropriately branded and provide login and registration for users at that site. +- **Third-party IDP:** + An Identity Provider not managed by ESGF but which could be hooked up to the IDP Proxy to provide additional login options for "homeless" users. e.g. GitHub, Google Plus, etc. +- **External IDP:** + Any IDP being relied on to provide an identity. e.g. A third-party or ESGF site-specific IDP. + +## Keycloak Functionality Overview + +Except where specified, the information in this section applies to both the ESGF IDP Proxy and site-specific ESGF IDP Keycloak servers. + +### Themes + +All Keycloak view templates can be edited or overridden with a custom theme. This allows for full customisation of the look-and-feel of Keycloak, as well as the content of each page. + +The IDP Proxy uses an ESGF styled theme to override much of the content of the default Keycloak views. For instance, it does not allow user's to login with a username and password. Instead, they authenticate with another ESGF IDP or with a third-party IDP. Site-specific ESGF IDPs retain the standard Keycloak functionality but alter the appearance with CSS. + +### Registration + +This is the process by which a visitor to the Keycloak server can enter their personal details to generate an account in a Keycloak server's database. Registration, by default, prompts for the following information: + +- First name (required) +- Last name (required) +- Email (required, unique) +- Username (required, unique) - Only if “Email as username” is not enabled. +- Password (required) + +The registration form contents can be modified in the relevant theme template. Additional information about the user can be requested this way by adding custom fields mapped to *user attributes* (explained in the next section). + +User registration is disabled on the IDP Proxy. Instead, a user record is created in the database when a user authenticates via an external IDP. The fields for this user are populated from their OIDC profile. + +### User Accounts + +Account information is stored as a row in the Keycloak database’s user table. + + - Each row in the user table of the database is automatically assigned a randomly generated unique ID, a realm ID, a timestamp, etc. + - Passwords are stored in a separate table. + - If an IDP is used to authenticate, a new user account is created. A many-to-many linking table is used to associate users with IDPs. + - If the “Email as username” realm option is enabled, the user’s username field will match their email address. + - When a new user authenticates with an external IDP, a row will be created in the user database from the `preferred_username`, `email`, `given_name` and `family_name` attributes of the OIDC ID token / UserInfo response. + +*User attributes* can be used to associate additional information with an account. + + - Attributes are arbitrary key/value pairs stored in their own table in the database and associated with users by ID. + - Attribute values can be provided to a relying party by adding them to a scope. + +Keycloak has a profile page, which users can access to change their account details. This also applies to federated users at the IDP Proxy, who would be able to alter their account details to be different to those of their home IDP. + +## Case 1: New User Registration and Login + +When a new user arrives at the IDP Proxy, they will be presented with a selection of IDPs. They will have two options: + +1. Sign in with a third party IDP such as GitHub, Google Plus, etc. + + - Selecting one of these providers will send them to the third party site's login page where they will be able to login with an existing account or create a new a account to login with. The external IDP will then communicate their account information to the IDP Proxy using OIDC, completing their registration and login at the IDP Proxy. + +2. Sign in with one of the available site-specific ESGF IDPs such as LLNL, CEDA, etc. + + - The user will be redirected to the login page of their chosen site's customised Keycloak IDP, where they will be able to register a new account (as detailed in the above section) and login. Their information will then be communicated with the IDP Proxy using OIDC, completing their registration and login at the IDP Proxy. + +Once an approved IDP has been used to register and authenticate at the IDP Proxy, the user's authenticated status and saved details can be passed on to a relying ESGF web application or service to complete their login. + +## Case 2: Legacy User Password Reset + +Users that had an account at an ESGF institution before the migration to Keycloak should be familiar with the available site-specific IDPs shown at the IDP Proxy login screen. + +However, once they are directed to their chosen IDP, they will not be able to login using their old password. This is because the ESGF user database migration did not transfer ESGF user passwords. Therefore, legacy users will have to reset their password at their organisation's Keycloak IDP before they can login. + +After they have reset their password and logged in, their old details will be saved to the IDP Proxy and authentication will be complete. + +## Case 3: Login with multiple IDPs + +There will be situations where users who have authenticated with one IDP in the past attempt to authenticate with a second IDP. Since the IDP Proxy creates a user record in its database when somebody first logs in, there must be a way to determine that a new user with the same email address or username as an existing user is the same person as that user. + +Fortunately, this is a fairly ordinary scenario for sites with external IDP providers, and Keycloak's solution should is quite simple: If either the `username` or the `email address` of a newly authenticated user matches that of user already in the database, the IDP Proxy will give you two options: + +1. Link the new user account with the one in the database. + + - This will redirect you back to the login page, where it expects you to log in to the proxy with the account that has the conflicting details (which may be the username or the email address, but only the one prompted for matters). Once logged in, that account will be associated with your new IDP, in addition to any others it might have been linked to. User details of the account are unchanged. + + - As implied by the above, in the scenario where the details of a user on two IDPs are different (e.g. a user with different usernames per organisation but the same email address, or vice versa) the proxy will only store the relevant details of the first account to authenticate. + +2. Change your email/username on the proxy + + - The proxy will let you change the details of your “new” proxy account before it is created. In other words, you will be able to change the username or email address to something that doesn’t conflict with an account already present on the proxy. + + - If the proxy is using the “Email as username” realm option, then the above flow will ignore “preferred_username” and simply use the user’s email address instead. With this enabled, account linking functions the same as described above, but without needing to compare usernames.