Created on 07-22-2020 02:48 AM - edited on 07-24-2020 03:07 AM by VidyaSargur
Co-authored by Balazs Gaspar and Steffen Maerkl - more coming soon
The purpose of this article is to describe how to set up Keycloak as a SAML 2.0 Identity Provider for CDP Public Cloud, enabling any user in your organisation to use single sign-on to access CDP and its services, such as Cloudera Machine Learning or Cloudera Data Warehouse.
Keycloak is a popular open source Identity and Access Management (IAM) solution but of course there are many more such solutions, so see this as one example. In an upcoming Cloudera Community post we plan to provide a similar guide for configuring CDP Public Cloud with other popular SSO solutions.
In the examples below we will create users and groups directly in Keycloak. In a real world deployment it is more likely that you would use Keycloak only for SSO and rely on a separate provider (such as Active Directory) to store users and groups via LDAP federation. If you have not been exposed to SAML 2.0 previously, Okta has an excellent guide for beginners, including a diagram depicting the SAML authentication flow between the Identity Provider (IdP) and the Service Provider (SP).
One benefit of SAML is that it does not require the IdP and the SP to communicate directly to each other, the authentication is performed by a token exchange through your browser session. Therefore you can use any SSO solution that supports SAML 2.0, including cloud SSO services as well as local or remote open-source deployments.
In the following we will present two methods:
Both methods enable you to run Keycloak on your localhost or a remote server (e.g. AWS EC2 or Azure VM).
Note: If you choose to deploy Keycloak on a remote server, make sure to set up and use a secure HTTPS connection to interact with the web interface (see SSL modes in the Keycloak documentation for details).
Setting up Keycloak locally or on a cloud machine is straightforward and requires no installation (also no elevated permissions are required) - see the Keycloak server system requirements for details.
Briefly, these are the requirements to run the server in standalone mode:
To download and extract the Keycloak server binaries, we do the following:
wget https://downloads.jboss.org/keycloak/10.0.2/keycloak-10.0.2.zip
unzip keycloak-10.0.2.zip
KEYCLOAK_HOME=`pwd`/keycloak-10.0.2
PATH=$PATH:$KEYCLOAK_HOME/bin
While setting the KEYCLOAK_HOME path is not mandatory, it certainly makes working with the Keycloak command-line tools much easier.
We can now create an admin user and start the server in the background.
# Create an admin user
add-user-keycloak.sh -r master -u admin -p admin
# Start the keycloak server and verify it is running
standalone.sh &
curl http://localhost:8080
Opening http://localhost:8080 in a browser will allow you to log in with the admin user that you just created (admin/admin). By default, Keycloak will only accept unencrypted HTTP connections from the localhost and will enforce HTTPS for remote connections only (see SSL modes), which we also strongly recommend.
Note: This option will not provide a persistent volume (unless you attach one) to store all the configs (realms, users, clients), so if you shut down the container your configuration will be lost.
Create an EC2 instance in AWS (we chose an Ubuntu 18.04) that meets the physical requirements listed in the Keycloak documentation (https://www.keycloak.org/docs/latest/server_installation/index.html) and make sure the Security Group you use allows incoming traffic on port 8443/22 to your IP address for the initial setup and configuration
SSH into the newly created EC2 instance and install the latest version of docker as described in the Docker documentation (https://docs.docker.com/install/linux/docker-ce/ubuntu/).
Bring up Keycloak by using the image (available in the public Docker Hub):
docker run -d -p 8443:8443 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin jboss/keycloak
Now that we have set up our Keycloak server, we can proceed in setting up our SAML Identity Provider.
Log in to the Keycloak Administration Console: http://localhost:8080 (or https://<IP address of the Keycloak instance>:8443)
Click on the Administration Console link and use admin/admin as the username and password to login.
Create a new realm as described in the documentation.
Still in Keycloak, on the Realm Settings screen click on the “SAML 2.0 Identity Provider Metadata” link listed under “Endpoints”, which will open the descriptor file for the realm you created in the previous step. Copy the XML content.
Sign in to CDP, click on the Management Console tile followed by User Management on the left.
Now navigate to the Identity Provider Tab and click on “Create Identity Provider”.
After you provided a name, select “Direct Input” under “Provider Metadata”, paste the XML content from the previous setup into the input field, and click on “Create”.
This adds the new identity provider to the list of CDP identity providers on the Identity Providers page.
Also, note that CDP will generate a unique identifier and assign it to your Identity Provider. This ID will be added to our Keycloak configuration in the next step.
As a next step, we will add the CDP Control Plane as a SAML 2.0 client that uses our Keycloak deployment as an identity provider. See SAML clients in the Keycloak documentation for further details.
We have two ways to perform this:
Both methods rely on the CDP service provider configuration that is linked to the Identity Providers page (https://console.cdp.cloudera.com/iam/downloads/saml-metadata.xml). You will use this file if you choose Option B / manual setup.
To simplify the process, the authors of this article have created a sample Keycloak client configuration in JSON based on the metadata.xml that you just downloaded from CDP. This includes the required settings, SAML assertion mappings as well as signing certificates required by CDP.
Please note that this is by no means an “official” client configuration provided by Cloudera, but is rather meant to simplify the SAML client setup for experimenting or PoC environments. For everything else, You may want to use the metadata XML document that describes the CDP Service Provider (see Option B and the related CDP documentation) and build your own SAML client configuration.
{
"clientId": "cdp-client",
"surrogateAuthRequired": false,
"enabled": true,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"https://consoleauth.altus.cloudera.com/saml"
],
"webOrigins": [
"https://consoleauth.altus.cloudera.com"
],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": true,
"protocol": "saml",
"attributes": {
"saml.assertion.signature": "true",
"saml.force.post.binding": "true",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"saml_assertion_consumer_url_post": "https://consoleauth.altus.cloudera.com/saml?samlProviderId={ID}",
"saml.server.signature": "true",
"saml_idp_initiated_sso_url_name": "cdp-sso",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"saml.signature.algorithm": "RSA_SHA256",
"saml_force_name_id_format": "false",
"saml.client.signature": "true",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "true",
"display.on.consent.screen": "false",
"saml_name_id_format": "username",
"saml.onetimeuse.condition": "false",
"saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"protocolMappers": [
{
"name": "my-email-id-mapper",
"protocol": "saml",
"protocolMapper": "saml-user-property-mapper",
"consentRequired": false,
"config": {
"attribute.nameformat": "URI Reference",
"user.attribute": "email",
"friendly.name": "my-email-friendly-name",
"attribute.name": "urn:oid:0.9.2342.19200300.100.1.3"
}
},
{
"name": "my-groups-mapper",
"protocol": "saml",
"protocolMapper": "saml-group-membership-mapper",
"consentRequired": false,
"config": {
"single": "true",
"attribute.nameformat": "URI Reference",
"full.path": "false",
"friendly.name": "my-groups-friendly-name",
"attribute.name": "https://altus.cloudera.com/SAML/Attributes/groups"
}
},
{
"name": "my-firstname-mapper",
"protocol": "saml",
"protocolMapper": "saml-user-property-mapper",
"consentRequired": false,
"config": {
"attribute.nameformat": "URI Reference",
"user.attribute": "firstName",
"friendly.name": "my-firstname-friendly-name",
"attribute.name": "https://altus.cloudera.com/SAML/Attributes/firstName"
}
},
{
"name": "my-lastname-mapper",
"protocol": "saml",
"protocolMapper": "saml-user-property-mapper",
"consentRequired": false,
"config": {
"attribute.nameformat": "URI Reference",
"user.attribute": "lastName",
"friendly.name": "my-lastname-friendly-name",
"attribute.name": "https://altus.cloudera.com/SAML/Attributes/lastName"
}
}
],
"defaultClientScopes": [
"web-origins",
"role_list",
"profile",
"roles",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
To create a SAML 2.0 client in Keycloak via the above JSON, we need to click “Create” on the Clients page and Import the cdp-client.json file with the above content. The Client ID and Client Protocol fields will be filled in automatically, Client SAML Endpoint can be blank.
Note that the four mappers we need are already configured here:
It is also worth noting that certain attributes in the configuration must be used exactly as in our example. CDP requires the four attributes to be named "urn:oid:0.9.2342.19200300.100.1.3" (or “mail” for short), "https://altus.cloudera.com/SAML/Attributes/groups", "https://altus.cloudera.com/SAML/Attributes/firstName" and "https://altus.cloudera.com/SAML/Attributes/lastName" (see the previously mentioned CDP documentation). When using Keycloak we also need to make sure to specify the proper user attributes “email”, “firstName” and “lastName”. Keycloak handles group membership assertion in a simplified way and will assert all groups of the user logging in via SSO. Other SSO providers offer a more sophisticated approach, enabling custom filtering or even group name transition during the SAML assertion.
While on the page, take note of the URL displayed under “IDP Initiated SSO URL Name” in the client settings page. If you have set up Keycloak on your local machine, this should be “Target IDP initiated SSO URL: https://localhost:8443/auth/realms/cdp/protocol/saml/clients/cdp-sso” or similar. We will use this URL to perform SSO login to CDP in Step 4 of our guide.
To finalize the SAML client setup, click Edit in the Client list, and on the bottom of the client details page open the section “Fine Grain SAML Endpoint Configuration”. Notice that the value is set to “https://consoleauth.altus.cloudera.com/saml?samlProviderId={ID}”. Replace {ID} with the Identity Provider ID generated by CDP in the previous step and click Save.
Create a new realm as described in the documentation.
Create a new Client by navigating to the Clients section and clicking on “Create”.
Import the saml-metadata.xml file that you download earlier from the CDP UI.
In the Client configuration, adjust the following parameters:
Last but not least you need to specify the Mappers.
Click on the “Mappers” tab and add four entries for each of the attributes described in the saml-metadata.xml file of CDP (Email, First Name, Last Name, and Groups). You can find the link under the Identity Providers tab in CDP.
You may note Email is the only mandatory attribute, whereas the First Name, Last Name, and Groups are optional.
Under the Mappers tab, click on “Create” (one entry for each of the four attributes):
Email (mandatory):
Name: email-mapper (or any arbitrary name)
Mapper Type: User Property
Property: email
Friendly Name: mail
SAML Attribute Name: urn:oid:0.9.2342.19200300.100.1.3
SAML Attribute NameFormat: URI Reference
First Name (optional):
Name: firstName (or any arbitrary name)
Mapper Type: User Property
Property: firstName
Friendly Name: firstName
SAML Attribute Name: https://altus.cloudera.com/SAML/Attributes/firstName
SAML Attribute NameFormat: URI Reference
Last Name (optional):
Name: lastName (or any arbitrary name)
Mapper Type: User Property
Property: lastName
Friendly Name: lastName
SAML Attribute Name: https://altus.cloudera.com/SAML/Attributes/lastName
SAML Attribute NameFormat: URI Reference
Groups (optional):
Name: groups (or any arbitrary name)
Mapper Type: Group list
Group attribute name: https://altus.cloudera.com/SAML/Attributes/groups
Friendly Name: groups
SAML Attribute NameFormat: URI Reference
Single Group Attribute: ON
Full group path: OFF
So far you have set up your Keycloak IdP, configured it in the CDP management console, and appended the unique ID to the Assertion Consumer Service POST Binding URL. As a final step to test the deployment we only need one more thing - users!
You can follow the Keycloak documentation to create a group, a user, and add that user to the group (see https://www.keycloak.org/docs/latest/server_admin/#groups for details). When creating the user, the following fields should be filled in:
“Username” is optional, as we will actually be passing the email attribute to CDP. Alternatively, you can also use “Username” instead of “Email”, just make sure to change the “Property: email” attribute for the “urn:oid:0.9.2342.19200300.100.1.3“ assertion in the previous step to “Property: username”.
In addition to the above, a password also needs to be created under the “Credentials” tab.
An example user setup is shown below.
Finally, we need to create a group (e.g “test-group”) and add our user to that group.
Now that we have a user with an email, first name, last name, and group membership, you can test how these are passed on to CDP. At the end of Step 3, we have located the URL for performing SSO authentication to access the CDP Management Console (this should be https://localhost:8443/auth/realms/cdp/protocol/saml/clients/cdp-sso or similar). Now, with Keycloak there are two ways to authenticate:
Clicking in the bottom left corner and selecting “Profile” will take you to the CDP account page of your use, which should look like this.
Notice that all attributes (email, first name, last name) have been properly asserted. Moreover, on the Groups tab, you can see that CDP automatically created the “test-group” and added your user. In case you are not able to see certain details (and see an error “Please contact your admin.”), make sure that your user or your group has at least the “IamViewer” role assigned in CDP.
Congratulations, you have successfully set up single-sign-on access to CDP!
As a next step, you can set up fine-grain permissions in CDP Identity Management that are enforced by Cloudera SDX when working with data in CDP. If you would like to understand the details, we recommend reading with the CDP Security Overview documentation.