How to connect your existing identity Provider with OpenID Client?

 

Content Hub Logo

Before we dive into the whole technical stuff. Let us take a step back and focus on the two parts of the blog post first. The first thing in the title is Single Sign-On, also more familiar as SSO. As Wikipedia explain is: Single sign-on (SSO) is an authentication scheme that allows a user to log in with a single ID and password to any of several related, yet independent, software systems. So basically for most of us, we see this when we log in on Windows and are automatically logged in when we browse to our intranet site for instance. We don't need to log in manually again. So a really great invention that makes our lives a whole lot easier.

At then we have the OpenID Client, also known as OIDC. So what is OIDC? According to openid.net:

OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.

OpenID Connect allows clients of all types, including Web-based, mobile, and JavaScript clients, to request and receive information about authenticated sessions and end-users. The specification suite is extensible, allowing participants to use optional features such as encryption of identity data, discovery of OpenID Providers, and session management, when it makes sense for them.

To simplify the matter, SSO is the idea and OIDC is the means to an end to get it done. Next to OIDC, the Content Hub also supports other out of the box:

  • Azure AD
  • Google
  • Microsoft
  • OpenID Connect
  • SAML
  • Sitecore
  • WS-Federation
  • Yandex
See the documentation for more information. For now, we focus on getting OIDC configured in the Content Hub.

Warning: Making changes to the Authentication settings isn't without risk. You could lose your access to the Content Hub. Therefore, please make the following preparations.

  1. Create a local Content Hub superuser account
  2. Create a copy of the Authentication settings and store it locally, before making any changes. This way you can always revert back to the original settings.
  3. Make sure to set the option authentication_mode to Passive, otherwise, you won't be able to log in via your local account
  4. Ask which claims are provided from your identity provider, in our case the OIDC provider. This will help you in a later phase to make the proper changes to the configuration.
  5. Ask for the well-known endpoint. This endpoint contains all the links to the required endpoints for OIDC
  6. Try this first in a non-production environment. This will give you confidence when making changes to the production version.
How to configure Content Hub?
For us to change the configuration, you will need superuser access in Content Hub. Go to the Manage page and click on Settings. Then continue with PortalConfiguration -> Authentication. Ideally, I now would copy over the entire setting value and save this on my local machine. When screwing up the setting, you can always revert back to the original value. Also, it makes it a whole lot easier to edit the JSON, when have it opened in a proper IDE. For JSON I prefer to use Notepad++ or Visual Studio Code, both are freely available to use. 

When we take a look at the documentation, you'll see we have the following options to configure for OIDC. 

"open_id_connect": [
        {
            "authentication_mode": "Passive",
            "client_id": "<ClientId>",
            "client_secret": "<ClientSecret>",
            "authority": "<Authority>",
            "get_claims_from_user_info_endpoint": false,
            "metadata_address": "<MetadataAddress>",
            "max_age": "<MaxAge>",
            "signed_out_redirect_uri": "<URL>",
            "authentication_method": "<AuthenticationMethod>",
            "response_mode": "<ResponseMode>",
            "response_type": "<ResponseType>",
            "prompt": "<Prompt>",
            "email_claim_type": "<ClaimTypeOverride>",
            "external_user_creation_url": "https://www.registerme.com",
            "is_enabled": true,
            "messages": {
                "signIn": "T_translationKey",
                "signInDescription": "T_translationKey",
                "signInTitle": "T_translationKey"
            },
            "provider_name": "OpenIdConnect,",
            "username_claim_type": "<ClaimTypeOverride>",
            "is_internal": false,
            "clear_default_scope": false,
            "scope": [
                "<CustomScope>"
            ]

Most of the properties are not needed and will have a default value when left out of the JSON. The following settings are the most important ones and must be correctly filled in.

PropertyDescription
client_idString (mandatory)
client_secretString (optional)
Default value = null.
metadata_addressString (optional)
Default value = null.
Enter the absolute URL from where to retrieve the metadata for the identity provider, which refers to the identity provider’s discovery endpoint (called a well-known endpoint).

These three settings are the ones you should start with. For the other options, please see the documentation. The most important thing you need to do: Talk with your identity provider supplies. They know what settings you need to set, to get this going. The instance, the response_type is by default id_token, but your supplier might ask you to change this to code. But only they will know, so keep a short line with them.

Other settings you need to check in the Authentication JSON are:

  • AutoCreateUsers
  • EnableCredentialless
These need to be set to True for the SSO to work. Make sure to check them if something fails.

When you've put everything together, you get something like this:

{
  "EnableEmailWhiteList": false,
  "EnableBasicAuthentication": true,
  "EnableRegister": false,
  "ShowRegister": false,
  "EnableExternalAuthentication": true,
  "EnableConfirmationMail": false,
  "EnableLockout": true,
  "MinutesToLockout": 5,
  "AttemptsBeforeLockout": 5,
  "AutoRestrict": false,
  "EnableCredentialless": true,
  "AutoCreateUsers": true,
  "CookieName": null,
  "CookieDomain": null,
  "PostSignOutRedirectUrl": "https://stylelabs.eu.auth0.com/v2/logout?returnTo=https://macaw-ct.stylelabs.io&client_id=JyVO5bQjk6n3mrUJnUZ02vMuA1K4MiaY",
  "EnableForgotPassword": false,
  "ShowForgotPassword": false,
  "PasswordExpiration": 129600,
  "PasswordRules": {
    "RequiredLength": 6,
    "RequireLowercase": true,
    "RequireUppercase": false,
    "RequireDigit": true,
    "RequireNonLetterOrDigit": false
  },
  "ReCaptcha": {
    "Key": null,
    "Secret": null
  },
  "ExternalAuthenticationProviders": {
    "global_username_claim_type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
    "global_email_claim_type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
    "saml": [
      {
        "metadata_location": "https://stylelabs.eu.auth0.com/samlp/metadata/JyVO5bQjk6n3mrUJnUZ02vMuA1K4MiaY",
        "sp_entity_id": "urn:stylelabs.eu.auth0.com",
        "idp_entity_id": "urn:stylelabs.eu.auth0.com",
        "provider_name": "SAML",
        "authentication_mode": "Passive",
        "module_path": "AuthServices",
        "is_enabled": true
      }
    ],
    "open_id_connect": [
      {
        "authentication_mode": "Passive",
        "get_claims_from_user_info_endpoint": false,
        "response_type": "code",
        "client_id": "clientId",
        "client_secret": "clientSecret",
        "metadata_address": "https://auth.pingone.eu/test/as/.well-known/openid-configuration",
        "signed_out_redirect_uri": "https://contenthubinstance.stylelabs.io/",
        "is_enabled": true,
        "messages": {
          "signIn": "Login via SSO",
          "signInTitle": "Login (SSO)"
        },
        "provider_name": "OpenIdConnect",
        "is_internal": false,
        "clear_default_scope": false,
        "scope": [
          "openid",
          "email"
        ]
      }
    ]
  }
}

What to do when things fail?

Start with checking the basics: client_id, client_secret and metadata_address. If all three are valid, continue with the response_type. When you see the SSO working, but failing in Content Hub, this might be caused by a misconfiguration of the claims. Under the setting ExternalAuthenticationProviders, you will find the global_username_claim_type and the global_email_claim_type check if you have these claims set up correctly. Depending on your supplier these might need to change. 

As mentioned earlier, keep in a close loop with your SSO supplier. They will probably help you solving your problem.

Happy codin'!