Sunday, 7 June 2015

OpenShift UI Console authentication with Keycloak and OpenID Connect

Two months ago OpenShift team implemented OpenID Connect support for authentication in its UI Console. Thanks to this work it can be easily integrated with Keycloak using fairly simple configuration. In this blog post I'll take you through example configuration process.

For complete documentation about configuration of authentication in OpenShift please check official guide here

Requirements:

  • Keycloak 1.2.0.Final zip distribution
  • Environment with properly installed and configured Docker 1.6. Steps below were verified on Fedora 22


Part 1 - Keycloak installation and SSL setup

OpenShift v3 requires usage of HTTPS and also verifies that requests are signed with valid Certificate Authority. For the purpose of this blog we'll take the shortest possible route and quickly generate our own CA and self signed certs. In practice even when using self signed certificates there are number of good practices to follow which we'll not cover here. Be warned that what is described below is not a proper production setup :)

Create a directory which will be used for Keycloak installation, certs and OpenShift configuration:
$ export DEMO_DIR=/home/bdaw/kc_os_demo 
$ mkdir $DEMO_DIR
$ cd $DEMO_DIR
$ mkdir certs
$ mkdir openshift
Those few commands below should generate dummy CA and a keystore for Keycloak with properly signed certificate. "localhost" should be used as a domain name and "secret" as a password.

$ cd certs
$ keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
Enter keystore password: secret
Re-enter new password: secret
What is your first and last name?
 [Unknown]: localhost
What is the name of your organizational unit?
 [Unknown]: IT
What is the name of your organization?
 [Unknown]: ACME
What is the name of your City or Locality?
 [Unknown]: Eden
What is the name of your State or Province?
 [Unknown]: Heaven
What is the two-letter country code for this unit?
 [Unknown]: AA
Is CN=localhost, OU=IT, O=ACME, L=Eden, ST=Heaven, C=AA correct?
 [no]: yes
Enter key password for <localhost>
 (RETURN if same as keystore password): secret
Re-enter new password: secret 
$ keytool -certreq -alias localhost -keystore keycloak.jks > keycloak.careq
Enter keystore password: secret 
$ openssl genrsa -out rootCA.key 2048 

$ openssl req -x509 -new -nodes -key rootCA.key -days 1024 -out rootCA.pem
-----
Country Name (2 letter code) [XX]:AA
State or Province Name (full name) []:Heaven
Locality Name (eg, city) [Default City]:Eden
Organization Name (eg, company) [Default Company Ltd]:ACME
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:localhost
Email Address []:adam@acme.org 
$ openssl x509 -req -in keycloak.careq -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out keycloak-ca.crt -days 500
Signature ok
subject=/C=AA/ST=Heaven/L=Eden/O=ACME/OU=IT/CN=localhost
Getting CA Private Key 
$ keytool -import -keystore keycloak.jks -file rootCA.pem -alias root
Enter keystore password: secret
(...)
Trust this certificate? [no]:  yes
$ keytool -import -alias localhost -keystore keycloak.jks -file keycloak-ca.crt
Enter keystore password: secret
Certificate reply was installed in keystore 
$ ls
keycloak-ca.crt keycloak.careq keycloak.jks rootCA.key rootCA.pem rootCA.srl

Now unzip keycloak and copy created keystore
$ cd $DEMO_DIR
$ cp <dir_with_your_kc_zip>/keycloak-1.2.0.Final.zip .
$ unzip keycloak-1.2.0.Final
$ cp $DEMO_DIR/certs/keycloak.jks $DEMO_DIR/keycloak-1.2.0.Final/standalone/configuration/
To configure Keycloak to use SSL you need to follow procedure described in documentation. As you already have properly generated and signed certs in a keystore only changes in standalone.xml need to be applied.

Open $DEMO_DIR/keycloak-1.2.0.Final/standalone/configuration/standalone.xml in your favourite text editor and apply changes listed below:

To the security-realms element add:
<security-realm name="UndertowRealm">
        <server-identities>
            <ssl>
                <keystore path="keycloak.jks" relative-to="jboss.server.config.dir" keystore-password="secret" />
            </ssl>
        </server-identities>
    </security-realm>
Find the element <server name="default-server"> (it's a child element of <subsystem xmlns="urn:jboss:domain:undertow:1.2">) and add:
<https-listener name="https" socket-binding="https" security-realm="UndertowRealm"/>
Additionally we need to avoid conflict with default ports used by OpenShift. Find and adjust line below to change port 8080 to 8180 and 8443 to 8543:
<socket-binding name="http" port="${jboss.http.port:8180}"/>
<socket-binding name="https" port="${jboss.https.port:8543}"/>

Part II - Keycloak Configuration - Realm and OpenID Connect client for OpenShift

Start Keycloak and create new realm for openshift configuration
$ cd $DEMO_DIR/keycloak-1.2.0.Final/bin
$ ./standalone.sh
Go to https://localhost:8543/auth/admin

Log in with credentials admin/admin

In the top right corner click on "Add realm" link. Use "openshift" as a name and click "Save". You can play with configuration a bit if you want - allowing user registration and etc.



As a next step create "openshift" client

On the left side click on "Clients" and then "create" button. Fill in "openshift" for both client ID and name and "https://localhost:8443/*" for valid redirect URIs. Leave all other fields with default values.

Go to "Credentials" tab and copy value of "secret" field. It will be needed later in OpenShift configuration.



To verify authentication we'll need a sample user. On the left side click on "Users" and then "Add user". Use "test-user" as a username and click save. Then go to "Credentials" tab and set new password - for simplicity just use "password" as a value and submit with Enter :)

Voila! Now Keycloak should be properly configured to provide authentication for OpenShift. As you can see above biggest part of it was actually not related to OpenID Connect and OpenShift at all but to proper generation of certificates and SSL configuration... :)

Part III Openshift installation and configuration

There are few different ways to install OpenShift which are described either in official documentation or on github. Fabric8 can be used as well as it was described by Marko in one of previous posts

Simplest way to obtain needed parts to try out UI authentication is to use docker image and this is the setup we'll follow.

Start another terminal windows (first one should be occupied with running Keycloak server).
$ export DEMO_DIR=/home/bdaw/kc_os_demo 
$ sudo docker run -it --name "openshift-origin" --net=host --privileged -v /var/run/docker.sock:/var/run/docker.sock -v $DEMO_DIR:/opt/demo/ openshift/origin start master --write-config="/opt/demo/openshift/config"
It should create configuration files and exit.

Open $DEMO_DIR/openshift/config/master-config.yaml in your favorite text editor and adust configuration as below.

Find "oauthConfig" section and replace whole "identityProviders" section under it with content below:
   identityProviders:
  - name: keycloak
    challenge: false
    login: true
    provider:
      apiVersion: v1
      kind: OpenIDIdentityProvider
      ca: /opt/demo/certs/rootCA.pem
      clientID: openshift
      clientSecret: fdceb89f-3fa7-4b6d-8780-06074de5c62e
      claims:
        id:
        - sub
        preferredUsername:
        - preferred_username
        name:
        - name
        email:
        - email
      urls:
        authorize: https://localhost:8543/auth/realms/openshift/tokens/login
        token: https://localhost:8543/auth/realms/openshift/tokens/access/codes

Important thing to not forget - replace "clientSecret" value with the one which you found in Keycloak Admin UI.

As you can see "ca" is pointing to our dummy CA certificate (rootCA.pem). Alternatively you can remove this line and just add this cert to your system. OpenShift will validate against system wide ones by default.

Additionally locate the line starting with "logoutURL" and point it to Keycloak:

logoutURL: "https://localhost:8543/auth/realms/openshift/protocol/openid-connect/logout?redirect_uri=https://localhost:8443/console"

That is pretty much everything which is required on OpenShift side

In the master-config.yaml you can see to which IP address container is bind by checking "masterPublicURL" value. Obviously there are few other and probably better ways to determine it upfront... :). In my case it is "https://192.168.0.19:8443". This URL needs to be added to "openshift" client configuration in Keycloak as "Valid Redirect URI".



Now you can start OpenShift container again:
$ sudo docker rm openshift-origin
$ sudo docker run -it --name "openshift-origin" --net=host --privileged -v /var/run/docker.sock:/var/run/docker.sock -v $DEMO_DIR:/opt/demo/ openshift/origin start master --config="/opt/demo/openshift/config/master-config.yaml"
Go to "https://localhost:8443/console" and log in as "test-user" with password "password". Please note that you can also logout and this will properly get propagated to Keycloak.


In case of any issues you should hopefully see a meaningful error message logged either by OpenShift or by Keycloak server. Most common problems are related to network connectivity between OS and KC, certificate validation on the OS side and having proper redirect URI whitelisted in Keycloak. 

Huge thanks to Jordan Liggitt who implemented OpenID Connect support in OpenShift and Rob Cernich who contributed to it and initially tested it with Keycloak. You guys rock! :) 

No comments:

Post a Comment

Please only add comments directly associated with the post. For general questions use the Keycloak user mailing list.