Skip to Content
Skip Breadcrumb

Some OpenShift environments require a single sign on ( SSO ) solution with some existing authentication backends like Active Directory and SAML .

Update: 25.04.2017 - add Client.json

Red Hat offers for this a ready to use image which is documented here , you should also take a look in to documentation of RH SSO .

You will need to setup keycloak, which is the product behind the Red Hat SSO.
Please take a loot at RedHat SSO setup for a detail documentation.

Normally you will go to the keycloak admin GUI and use the interactive setup, which is perfectly okay as long as your setup is only for one environment and only once.

❗️ | In case you want to setup the SSO for several environments and several times you want a more reproducible process then the Mouse & Remind process .

I will describe here some commands which you can use to create your own automation scripts and processes.

First of all you will find in the internet the command kcadm to admin keycloak. This is a very handy and useful tool so let us use it for the next steps.

Please download the Standalone server distribution from the keycloak home and extract it.

You should now have in the bin directory the kcadm files as shown in the screenshot.

KC-kcadm

To be able to run this script you will need a java runtime on the executing machine.

❗️ | Please give you some time to create the right command lines and json files for YOUR Setup.

Now you can login into your RedHat SSO (Keycloak)

# kcadm.bat config credentials \
    --server https://secure-sso<your-domain>/auth \
    --realm master \
    --user your-SSO_ADMIN_USERNAME \
    --password your-SSO_ADMIN_PASSWORD

To see more options of the command config credentials just use --help .

Now you can use kcadm with the following commands

Download/keycloak/keycloak-3.0.0.Final/keycloak-3.0.0.Final/bin/kcadm.bat
...
Commands:
  config        Set up credentials, and other configuration settings using the config file
  create        Create new resource
  get           Get a resource
  update        Update a resource
  delete        Delete a resource
  get-roles     List roles for a user or a group
  add-roles     Add role to a user or a group
  remove-roles  Remove role from a user or a group
  set-password  Re-set password for a user
  help          This help

Use 'kcadm.bat help ' for more information about a given command.

Please give you some time to create the right command lines and json files for YOUR .

The commands shown in this blog are created with the browser network tools and the Keycloak API document.

Please take a look into the Support page to find the right Documentation version for your setup.

To create a new realm execute this

# kcadm.bat create realms 
-s realm=MY-REALM
-s enabled=true
-s displayName="MY Realm"
and now add the openshift client into the realm.

The important part is the secret.

This secret will be configured into the openshift master config as described in the Chapter OpenID Connect .

# kcadm create clients 
-f client.json
-r MY-REALM
-s secret=THE-PASSWORD
-s clientId=openshift-001
-H
the client.json looks like this
{
    "surrogateAuthRequired": false,
    "enabled": true,
    "clientAuthenticatorType": "client-secret",
    "redirectUris": ["https://YOUR-OSCP-URL/*", ...],
    "webOrigins": [],
    "notBefore": 0,
    "bearerOnly": false,
    "consentRequired": false,
    "standardFlowEnabled": true,
    "implicitFlowEnabled": false,
    "directAccessGrantsEnabled": true,
    "serviceAccountsEnabled": false,
    "publicClient": false,
    "frontchannelLogout": false,
    "protocol": "openid-connect",
    "attributes": {
        "saml.server.signature": "false",
        "saml.assertion.signature": "false",
        "saml.client.signature": "false",
        "saml.encrypt": "false",
        "saml.authnstatement": "false",
        "saml_force_name_id_format": "false",
        "saml.multivalued.roles": "false",
        "saml.force.post.binding": "false"
    },
    "fullScopeAllowed": true,
    "nodeReRegistrationTimeout": -1,
    "protocolMappers": [{
        "name": "given name",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-usermodel-property-mapper",
        "consentRequired": true,
        "consentText": "${givenName}",
        "config": {
            "user.attribute": "firstName",
            "id.token.claim": "true",
            "access.token.claim": "true",
            "claim.name": "given_name",
            "jsonType.label": "String"
        }
    },
    {
        "name": "email",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-usermodel-property-mapper",
        "consentRequired": true,
        "consentText": "${email}",
        "config": {
            "user.attribute": "email",
            "id.token.claim": "true",
            "access.token.claim": "true",
            "claim.name": "email",
            "jsonType.label": "String"
        }
    },
    {
        "name": "username",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-usermodel-property-mapper",
        "consentRequired": true,
        "consentText": "${username}",
        "config": {
            "user.attribute": "username",
            "id.token.claim": "true",
            "access.token.claim": "true",
            "claim.name": "preferred_username",
            "jsonType.label": "String"
        }
    },
    {
        "name": "role list",
        "protocol": "saml",
        "protocolMapper": "saml-role-list-mapper",
        "consentRequired": false,
        "config": {
            "single": "false",
            "attribute.nameformat": "Basic",
            "attribute.name": "Role"
        }
    },
    {
        "name": "family name",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-usermodel-property-mapper",
        "consentRequired": true,
        "consentText": "${familyName}",
        "config": {
            "user.attribute": "lastName",
            "id.token.claim": "true",
            "access.token.claim": "true",
            "claim.name": "family_name",
            "jsonType.label": "String"
        }
    },
    {
        "name": "full name",
        "protocol": "openid-connect",
        "protocolMapper": "oidc-full-name-mapper",
        "consentRequired": true,
        "consentText": "${fullName}",
        "config": {
            "id.token.claim": "true",
            "access.token.claim": "true"
        }
    }],
    "useTemplateConfig": false,
    "useTemplateScope": false,
    "useTemplateMappers": false
}
Now we need to add the user-federation with Active Directory.
# kcadm create user-federation/instances 
-f user-federation-YOUR-AD.json
-r MY-REALM
-H
the user-federation json looks like this
{
    "providerName": "ldap",
    "config": {
        "syncRegistrations": false,
        "userAccountControlsAfterPasswordUpdate": true,
        "connectionPooling": true,
        "pagination": true,
        "allowKerberosAuthentication": false,
        "debug": false,
        "useKerberosForPasswordAuthentication": false,
        "authType": "simple",
        "batchSizeForSync": "1000",
        "searchScope": "1",
        "useTruststoreSpi": "ldapsOnly",
        "editMode": "READ_ONLY",
        "vendor": "ad",
        "usernameLDAPAttribute": "cn",
        "userObjectClasses": "person, organizationalPerson, user",
        "rdnLDAPAttribute": "cn",
        "uuidLDAPAttribute": "objectGUID",
        "connectionUrl": "YOUR-LDAPS-URL",
        "usersDn": "YOUR-USERS-DN",
        "bindDn": "YOUR-BIND-DN",
    },
    "priority": 0,
    "displayName": "MY-AD"
}
The Keycloak is now configured to ask for the user authentication the AD.

Now you need to configure openshift to offer this authentication method to the user. The preferred  way is to Configuring Identity Providers with Ansible to be on the safe site. Openshift can use more then one identity provider, due to this fact you can use a fail-safe htpasswd file for some dedicated administrators.

This is a example line which you can use in your ansible inventory file.

openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider', 'filename': '/etc/origin/htpasswd'},{'name': 'YOUR-OAuth', 'login': 'true', 'challenge': 'false', 'mappingMethod': 'claim', 'kind': 'OpenIDIdentityProvider','clientID': 'openshift-001','clientSecret': '<THE-PASSWORD>', 'claims':{'id':['sub'],'preferredUsername':['preferred_username'],'name':['name'],'email':['email']},'urls':{'authorize':'https://secure-sso<your-domain>/auth/realms/MY-REALM/protocol/openid-connect/auth','token': 'https://secure-sso<your-domain>/auth/realms/MY-REALM/protocol/openid-connect/token','userInfo':'https://secure-sso<your-domain>/auth/realms/MY-REALM/protocol/openid-connect/userinfo'}}]
I hope you have tested via curl that the master(s) can reach the URL https://secure-sso<your-domain>/ .

You can run now the ansible playbook which you have used for your setup and hope that you see the new authentication method 😏 .

You can contact me for any further questions and orders