Introduction

Keycloak is an open source identity and access management platform, and it provides support for standard protocols like OpenID Connect, OAuth 2.0, and SAML.

In this tutorial, SAML will be used in Keycloak to enable Single Sign-On (SSO) capability with Joget.

This tutorial serves only as a general guide, using minimal-required configurations on Keycloak to enable SSO via SAML protocol with Joget.

To use Keycloak in a production environment, please see Configuring Keycloak for production or other relevant Keycloak guides.

Prerequisites

Tutorial Steps

1. Keycloak Installation

To quickly get started on Keycloak and for ease of testing, we recommend installing Keycloak via Docker in your local development environment.
Do follow the guide until the part where you have successfully created a sample user in Keycloak & verify by logging in with this new user credentials in the Keycloak Account Console.

In this tutorial, it is presumed that the Keycloak instance will be running and exposed on the same host machine running your Joget instance. 

In this case, since the default bundled Tomcat server hosting the Joget platform operates on port 8080 by default, do ensure the deployed Keycloak container does not clash with the same host port.

For example, you can map Keycloak container to expose on host port 8500 or any other non-clashing port instead. 

At this point of time after completing the Keycloak installation tutorial, you should have these ready in Keycloak:

2. Plugin Installation

  1. Download the SAML Directory Manager Plugin from the Joget Marketplace, and upload the plugin .jar file into your Joget instance.
    This plugin's source code is also available in JogetOSS Github. Projects under JogetOSS are community-driven and community-supported, and you are welcome to contribute to the projects.

  2. Then, in Admin Bar → Settings → General Settings → API IP Whitelist, do whitelist external IP addresses. For now, you can allow all public users (using * symbol to indicate "allow all").
    This is to allow end user browsers to communicate with the SAML plugin.



  3. Save the settings.

3. Plugin Configuration

  1. In Admin Bar → Settings → Directory Manager Settings → Select Plugin, select SAML Directory Manager to start configuring the plugin.



  2. Copy both values of Entity ID and ACS URL, and temporarily save these values in a convenient place for later use.
    These values are required in order to create a valid client in Keycloak.

    Do also ensure User Provisioning Enabled option is checked. This will automatically create user accounts for SSO users that does not exist yet in Joget.



  3. Next, you'll need the IDP Certificate value from Keycloak in order to finish configuring the SAML Directory Manager plugin. 
    Log into your Keycloak Admin Console, ensure you are currently in myrealm, then go to Realm Settings → Keys, and copy the RS256 Certificate value.




  4. Paste the RS256 Certificate value in the IDP Certificate field.



  5. The SAML Directory Manager plugin is a superset of Security Enhanced Directory Manager plugin.
    Hence, the remainder of the plugin configurations (e.g.: Default Directory Password Policy, Notification, etc.) is identical, and you can refer to the Security Enhanced Directory Manager documentation.

  6. Save the plugin configuration.
    From here onwards, the only remaining configurations to perform are on the Keycloak Admin Console side.

4. KeyCloak Configuration

  1. In your Keycloak Admin Console, go to myrealm, create a new client.



  2. For Client Type, select SAML.
    For Client ID, paste in the Entity ID value you've copied earlier from the SAML Directory Manager plugin.



    Click "Next".

    For Valid Redirect URIs, paste in the base URL of your Joget instance.
    For both  



  3. Save the client configuration.

  4. Next, we'll still need to modify more configurations for our newly created client.
    Edit the client configuration.



    Then, refer to the tables below to ensure the remaining config values are correct.

    "Settings" tab

    General settings
    Client ID

    (Paste in the Entity ID copied from the SAML Directory Manager plugin)

    Example:

    http://localhost:8080/jw/web/json/plugin/org.joget.plugin.saml.SamlDirectoryManager/service

    Name--OPTIONAL--

    Description

    --OPTIONAL--

    Always display in UI

    Off

    Access settings

    Root URL

    --blank--

    Home URL

    --blank--

    Valid redirect URIs

    (Base URL of your Joget instance)

    Example: http://localhost:8080/jw

    Valid post logout redirect URIs

    --blank--

    IDP-Initiated SSO URL name

    (Paste in the ACS URL copied from the SAML Directory Manager plugin)

    Example:

    http://localhost:8080/jw/web/json/plugin/org.joget.plugin.saml.SamlDirectoryManager/service

    IDP Initiated SSO Relay State

    --blank--

    Master SAML Processing URL

    (Paste in the ACS URL copied from the SAML Directory Manager plugin)

    Example:

    http://localhost:8080/jw/web/json/plugin/org.joget.plugin.saml.SamlDirectoryManager/service

    SAML capabilities

    Name ID format

    username

    Force name ID format

    On

    Force POST binding

    Off

    Force artifact binding

    Off

    Include AuthnStatement

    On

    Include OneTimeUse Condition

    Off

    Optimize REDIRECT signing key lookup

    Off

    Allow ECP flow

    Off

    Signature and Encryption

    Sign documents

    Off

    Sign assertions

    On

    Signature algorithm

    RSA_SHA256

    SAML signature key name

    CERT_SUBJECT

    Canonicalization method

    EXCLUSIVE

    Login settings

    Login theme

    --OPTIONAL--

    Consent required

    Off

    Display client on screen

    Off

    Consent screen text

    --blank--

    Logout settings

    Front channel logout

    Off

    "Keys" tab

    Signing keys config
    Client Signature RequiredOff
    Encryption keys config
    Encrypt assertionsOff

    "Roles" tab

    Default. No change.

    "Sessions" tab

    Default. No change.

    "Advanced" tab

    Default. No change.


  5.  Next, navigate to Client scopes tab, and click on the dedicated scope for Joget client, and add these 3 predefined mappers:
    • X500 email
    • X500 givenName
    • X500 surname





  6. Then, edit these 3 mappers, and replace the SAML Attribute Name to their intended values.
    Do refer to the table below for their respective replacement values.



    Mapping Name

    SAML Attribute Name

    X500 surname

    User.LastName

    X500 givenName

    User.FirstName

    X500 email

    email



  7. Save the client configuration.
    Now, we are ready to test the SSO functionality.
     

5. Test SSO to validate successful configuration

In the final phase, we should test if SAML SSO works with Keycloak & that Joget is able to correctly retrieve the sample user data from Keycloak as well.

To manually emulate an idP-initiated SSO login, we simply need to find the target IDP initiated SSO URL and test this URL in our browser.


The format of the target IDP initiated SSO URL is as such below.
Do refer to your overall Keycloak & Joget client configurations to fill in the blanks.

{server-root}/realms/{realm}/protocol/saml/clients/{client-id}

An example of the fully-qualified URL will look as such below:

http://localhost:8500/realms/myrealm/protocol/saml/clients/http%3A%2F%2Flocalhost%3A8080%2Fjw%2Fweb%2Fjson%2Fplugin%2Forg.joget.plugin.saml.SamlDirectoryManager%2Fservice

For the {client-id}, since the client ID itself is a URL, this value need to be in a URL-encoded format.

You can use various free online tools to help convert to the URL-encoded value.


Finally, you can navigate to this fully-qualified URL via an incognito tab in your browser.

You should see the Keycloak login page, and upon successful login, you will be redirect to the Joget App Center, and thus indicate this exercise is completed successfully.





Optional Modifications

Addon SSO button on login page

You can also allow end users to SSO via Keycloak with a convenient button in your Joget login page.

Edit the App Center app, navigate to UI builder -> Settings -> Login Page UI --> Custom HTML (After Login Form), then paste in the code snippet below.

<div class="custom-logins" style="place-items: center; width: 100%;">
<hr>
<a href='{Your-target-IDP-initiated-SSO-URL}' class='btn' style="display: block; width: 100%;">Login with Keycloak</a>
</div>
<script>
$(document).ready(function() {
   const customLogins = $("div.custom-logins").detach();
   $('#loginForm table').after(customLogins);
});
</script>


Result: