====== Single-Sign-On into Keycloak using Admidio as an OpenID Provider ====== Starting with version 5.0, Admidio can be used by other applications to authenticate users against Admidio's user base. These instructions will guide you through the process of connecting Keycloak to Admidio to use Admidio's login. For general instructions, and other apps, please visit the [[en:2.0:single_sign_on|general Single-Sign-On overview page]]. Keycloak supports both SAML 2.0 and OpenID out of the box, so no additional extensions or plugins are needed. ===== Prerequisites ===== Throughout the document we will assume you have both Admidio and Keycloak already set up properly at https://admidio.local/ and https://keycloak.local/. Please modify these URLs to your actual installation. As a first step, one needs to **configure Admidio to act as an OpenID Provider** (OP). This has to be done once and is not specific to Keycloak. Please follow this guide: [[en:2.0:single_sign_on|#a_basic_setup_for_admidio_as_an_oidc_id_provider]] {{ :en:2.0:sso:sso_oidc_01-05_setup_admidio_preferences.png?direct&600 |}} Basically, one (1) needs to **create a cryptographic key** to sign message and **choose a unique EntityID**. The page https://admidio.local/adm_program/modules/preferences.php?panel=sso also provides the link to the metadata xml, and the individual settings in case a client does not support auto-configuration via metadata. ===== Quick Overview ===== Setting up a client (OpenID "Relying Party" - short RP) to use Admidio's user accounts for logging in consists of two steps: (1) The client (RP, Keycloak in our case) needs to be set up with the data about the OpenID Provider (OP). Typically this is done via the metadata provided in the discovery URL of the provider. Otherwise one has to manually paste the endpoint URLs of the OpenID provider. Since Admidio provides those URLs with copy buttons in the preferences screen, even the manual configuration is rather straigtforward. (2) Admidio needs to be told about the client. In particular, the entity ID and the redirect URL must be given, and a custom-generated (random) secret must be copied to the client configuration. The concrete steps are: * At the **Relying Party (RP)** - Keycloak in our case - **set up** support for OpenID login. * Configure it with Admidio's **discovery URL** to auto-load the correct settings from Admidio. * Also, choose which scopes (groups of profile fields) should be requested from Admidio ("openid" is required; If Admidio's groups/roles should be mapped to the client's groups, the "groups" scope is also required). * In **Admidio**, **create a new OpenID client**. * Choose an easily understood **label for the client** (only used in Admidio's list of clients, but has no technical use) * Enter the **ClientID from the RP**, Copy the created **Client Secret** (you will later need to paste it indo Keycloak's configuration), and enter the **Redirect URI** for the RP. Typically the latter can be found either on the RP's configuration page or in the documentation. * Optionally select (both in Admidio and the RP) which **profile fields should be mapped** to OpenID claims (attributes) and sent to the client, and configure which **group memberships** should be transmitted and how they correspond to groups/roles in Keycloak. ===== Keycloak-specific instructions ===== ==== Configuring the Service Provider (Keycloak) ==== Keycloak provides SAML 2.0 and OpenID Connect support out of the box. It even supports multiple SAML and OpenID Connect Identity Providers (IdP). To add Admidio as an Identity Provider to log into Keycloak, go to your desired realm, choose "Identity Providers" on the left and add a new "SAML v2.0" Provider. {{ :en:2.0:sso:sso_oidc_keycloak_01_add_idp.png?direct&600 |}} Keycloak supports auto-configuration, so copy the OpenID Metadata URL from Admidio's preferences and paste it into the "Discovery Endpoint" field. Keycloak will load the OpenID Provider configuration from Admidio and populate all fields. {{ :en:2.0:sso:sso_oidc_keycloak_02_idp_discovery.png?direct&600 |}} Before the client can be saved/added, one needs to create the corresponding client in Admidio and copy the client secret into Keycloak. ==== Setting up the Client (SP) in Admidio ==== It is now a good idea to keep two browser windows open so one can easily select and copy the settings. Admidio even provides little "copy" buttons/icons to copy the various settings to the clipboard for easy pasting into Keycloak's configuration. Return to Admidio's SSO preferences page, go to the "Single-Sign-On Client Administration" (the button right below the endpoint URLs and above the "Save" button), and create a new client. {{ :en:2.0:sso:sso_oidc_01-07_clientadmin.png?direct&400 |}} * The **Client Name** is the label of the client in Admidio's client list, it can be anything you like. It will be shown to the users in the headline of the login form. * The "Client ID" is used to uniquely identify the Keycloak installation when a login request is received by Admidio. In principle, it can be any unique identifier, but it is customary to use the base URL of the installation. Just make sure that exactly the same Client ID is used in Keycloak and Admidio (even trailing slashes have to match exactly!). * The Client Secret is a random string and will serve like a password. Admidio will create one and allow it to be copied to the client. Afterwards it is only stored as a hash in the database and not be recovered any more. However, one can create a new Client Secret in Admidio and copy that to the client's configuration. **Copy both the Client Name and the Client Secret to Keycloak**, and at the same time copy the provided **Redirect URL from Keycloak to Admidio**. {{ :en:2.0:sso:sso_oidc_keycloak_04_clientsetup.png?direct&850 |}} You can now **click "Add"** to save the OpenID Provider in Keycloak and allow further configuration: * Enter the **scopes** you desire in Keycloak's config and make sure that Admidio's config matches them. At least **openid must be included** (Admidio will implicitly add it). OpenID defines a set of well-known profile fields, so Keycloak will (in contrast to the SAML provider)automatically populate the name, email and username if the corresponding scopes are requested. {{ :en:2.0:sso:sso_oidc_keycloak_03_configure_scopes.png?direct&600 |}} After saving the settings both in Admidio and Keycloak, the Keycloak plugin is ready for a test run and the final touches of the configuration. ==== Profile Attributes from Admidio ==== Admidio can be configured to send any profile field as an OpenID claim in the "custom" scope in the login response. {{ :en:2.0:sso:sso_oidc_keycloak_04a_admidio_fieldsmapping.png?direct&400 |}} The OpenID specification defines several claims in the profile, address, phone and email scopes, which will be automatically used by Keycloak for the name, email and username fields. However, other fields are not automatically mapped to Keycloak profile fields. One can set up attribute mappers in Keycloak to use OpenID claim and assign them to the user's profile. Go to the "Mappers" tab of the OpenID provider in Keycloak and add new mappers of type "Attribute Importer". It is a good idea to choose "Force", which will always update the keycloak user with the value from Admidio on every login. The "Claim" is the OpenID claim provided by Admidio, while the "User Attribute Name" is Keycloak's profile field name. {{ :en:2.0:sso:sso_saml_keycloak_04c_config_mappers.png?direct&600 |}} {{ :en:2.0:sso:sso_oidc_keycloak_04b_fieldsmapping.png?direct&400 |}} ==== Further configuration in Keycloak: Groups and Roles ==== Keycloak uses the term "Role" to refer to a particular permission (e.g. view users, manage users, delete account, etc.) and uses "Group" to refer to a set of roles that can be assigned to a user in bulk. Keycloak's Mapper feature allows Admidio groups to both assign individual roles to a user, or assign the user to a particular group (which gives all permissions defined for that group). For this to work, clearly, Admidio must be configured to include the Admidio roles of a user as SAML attribute (typically called "roles" or "groups", but any other name will work, too, as long as the new name is properly used in Keycloaks mapper). Use either the "Advanced Attribute to Group" or the "Advanced Attribute to Role" Mapper type. {{:en:2.0:sso:sso_oidc_keycloak_05_groupsmapping.png?direct&450|}}{{:en:2.0:sso:sso_oidc_keycloak_05_rolesmapping.png?direct&450|}} This will result in groups and roles assignments as in the following screenshots (they show the situation after a successful login, so they do NOT constitute a step in the setup, but rather illustrate the effects of the mapper!): {{:en:2.0:sso:sso_oidc_keycloak_05a_groupsmapped.png?direct&450|}}{{:en:2.0:sso:sso_oidc_keycloak_05a_rolesmapped.png?direct&450|}} After saving, the configuration of the OpenID Provider in Keycloak is finished and login via OpenID Connect should be possible. ==== Setup completed, test Single-Sign-On ==== Admidio and Keycloak should now be set up to use Admidio for logging in to Keycloak. If you log out of Keycloak (or open Keycloak in an incognito browser window) and go to the keycloak admin location, you should see the login screen with the choice of logging in with password or via OpenID. {{ :en:2.0:sso:sso_oidc_keycloak_07_loginform.png?direct&400 |}} After choosing OpenID login and logging in with a user from Admidio, you should also be logged in into Keycloak. {{ :en:2.0:sso:sso_oidc_keycloak_08_admidio_loginform.png?direct&400 |}} Your user should now be logged in and have the proper permissions/roles {{ :en:2.0:sso:sso_oidc_keycloak_10_linkedaccounts.png?direct&600 |}} ===== Multiple SSO providers for the same account ===== If the account already exists (e.g. because you are in a hybrid setup with multiple identity providers, e.g. SAML and OpenID through Admidio), then Keycloak will ask for permission to add the SAML login to the existing account. The user must additionally log in to the existing account to prevent security issues: {{:en:2.0:sso:sso_saml_keycloak_09_login_accountexists.png?direct&400|}}{{:en:2.0:sso:sso_saml_keycloak_10_login_link_login.png?direct&400|}} {{ :en:2.0:sso:sso_oidc_keycloak_10_linkedaccounts.png?direct&600 |}}