Author: Aaren DeJong


In recent efforts testing OpenShift 4.2, one of our more popular k8s distributions, I came across a case where it could be a little more clear, how the pieces go together to allow your OpenShift 4 cluster to have authentication provided by Azure Active Directory (AD). Do bear in mind that Azure AD is not to be confused with “proper” Microsoft Windows Active Directory in any way. We’re working with Azure Active Directory.

If you’ve been working with Azure, you’ve come to appreciate, like with all the major cloud providers, that it can offer authentication for users to your environments as long as they play in the right format. Azure AD qualifies as an OpenID authentication provider. The official OCP4.2 documentation does cover adding an OpenID auth provider, but it has some points I believe are important for Azure-deployed clusters.

The following quick list tells you what this setup entails, and then I dive into details below that.

  • We assume a ready-and-running OpenShift 4.1+ cluster
  • Login to Azure and OCP at web and CLI
  • Setup Azure app-registration, a.k.a. service-principal
  • Add a custom resource of the identityProviders for openID to your OAuth object in the Cluster Settings
  • Let the operator do its thing
  • Test that it works with cookie-cleared browser sessions to properly validate it works

So before you begin, remember to gather all the generated ID values and secrets for things, as that’s how they’re referenced, and need to be exact. This entire run-thru is due to be automated, but I’m focusing on getting it done right, first.

  1. login to your OCP4 cluster and create a secret, noting the name so it can be referenced in your Custom Resource (CR)
 oc create secret generic this-secret --from-literal=clientSecret='[email protected]' -n openshift-config
  1. login to Azure and create a Service Principal (SP), a.k.a. App-Registration and use the same secret value. The reply URL much be the console address with /oauth2callback/azureAD appended. Note that the azureAD part is what we’re naming the auth provider and will look as such in the login page.
 az ad app create --display-name OCP4AAD --homepage https://console-openshift-console.apps.ocplab.ocp4.local --reply-urls https://console-openshift-console.apps.ocplab.ocp4.local/oauth2callback/azureAD --identifier-uris https://console-openshift-console.apps.ocplab.ocp4.local --password '[email protected]'
  1. When the app-registration/SP is created, the output should look like this (or show the same with the command)…
 az ad sp show --id <id of the app reg>
 {
   "accountEnabled": "True",
   "addIns": [],
   "alternativeNames": [],
   "appDisplayName": "OCP4AAD",
   "appId": "<app reg id redacted>",
   "appOwnerTenantId": "<tenant/directory id redacted>",
   "appRoleAssignmentRequired": false,
   "appRoles": [],
   "applicationTemplateId": null,
   "deletionTimestamp": null,
   "displayName": "OCP4AAD",
   "errorUrl": null,
   "homepage": "https://console-openshift-console.apps.ocplab.ocp4.local",
   "informationalUrls": {
     "marketing": null,
     "privacy": null,
     "support": null,
     "termsOfService": null
   },
   "keyCredentials": [],
   "logoutUrl": null,
   "notificationEmailAddresses": [],
   "oauth2Permissions": [
     {
       "adminConsentDescription": "Allow the application to access OCP4AAD on behalf of the signed-in user.",
       "adminConsentDisplayName": "Access OCP4AAD",
       "id": "<redacted id>",
       "isEnabled": true,
       "type": "User",
       "userConsentDescription": "Allow the application to access OCP4AAD on your behalf.",
       "userConsentDisplayName": "Access OCP4AAD",
       "value": "user_impersonation"
     }
   ],
   "objectId": "redacted",
   "objectType": "ServicePrincipal",
   "odata.metadata": "https://graph.windows.net/<redacted>/$metadata#directoryObjects/@Element",
   "odata.type": "Microsoft.DirectoryServices.ServicePrincipal",
   "passwordCredentials": [],
   "preferredSingleSignOnMode": null,
   "preferredTokenSigningKeyEndDateTime": null,
   "preferredTokenSigningKeyThumbprint": null,
   "publisherName": "arctiq.ca",
   "replyUrls": [
     "https://console-openshift-console.apps.ocplab.ocp4.local/oauth2callback/OCP4AAD"
   ],
   "samlMetadataUrl": null,
   "samlSingleSignOnSettings": null,
   "servicePrincipalNames": [
     "https://console-openshift-console.apps.ocplab.ocp4.local",
     "<redacted id>"
   ],
   "servicePrincipalType": "Application",
   "signInAudience": "AzureADMyOrg",
   "tags": [
     "WindowsAzureActiveDirectoryIntegratedApp"
   ],
   "tokenEncryptionKeyId": null
 }-
  1. Create and/or apply the custom resource file oc apply -f OR use web ui and populate.
  • note: the issuer should be with your tenant id as follows:
     issuer: '[https://login.microsoftonline.c](https://login.microsoftonline.com/<tenant or directory id redacted>'
    
  • your clientID is the azure application/client ID of the SP/app-reg you created
  • the identityProvider ‘name’ value will be what you select in the UI of OCP when you land at its console URL

The CR should look a bit like this:

 spec:
   identityProviders:
     - mappingMethod: claim
       name: azureAD   <-- will be the name of the provider seen in the web UI
       openID:
         claims:
           email:
             - email
           name:
             - name
           preferredUsername:
             - preferred_username
         clientID: <app-reg/client ID>
         clientSecret:
           name: this-secret  <-- the one you created earlier
         extraScopes: []
         issuer: 'https://login.microsoftonline.com/<tenant or directory-id>'
       type: OpenID
  1. Note that the id provider name is the same as the name used in the redirect URI.
  • https://oauth-openshift.apps.ocplab.ocp4.local/oauth2callback/azureAD

  • --reply-urls https://console-openshift-console.apps.ocplab.ocp4.local/oauth2callback/azureAD

With everything saved and in place, the OCP web console now has the azureAD provider to select, which offers to log in to Azure portal, and then sends you into the cluster as a normal user. Remember that to do anything more than a basic user, groups with roles or roles alone should be associated with any users that log in.

In the end you should also see the auth provider you’ve enabled in the OAuth panel and at the login page:

oauth ui
login page

For clarity, the CR or identity provider YAML, in entirety would look a bit like this..

apiVersion: config.openshift.io/v1
 kind: OAuth
 metadata:
   annotations:
     release.openshift.io/create-only: 'true'
   name: cluster
spec:
  identityProviders:
    - mappingMethod: claim
      name: azureAD   <-- will be the name of the provider seen in the web UI
      openID:
        claims:
          email:
            - email
          name:
            - name
          preferredUsername:
            - preferred_username
        clientID: <app-reg/client ID>
        clientSecret:
          name: this-secret  <-- the one you created earlier
        extraScopes: []
        issuer: 'https://login.microsoftonline.com/<tenant-id>'
      type: OpenID
  1. Testing!

In order to properly test, be aware the portal.azure.com (and all of microsoft online) has very sticky cookies for caching login tokens. To get around this while testing, there’s a really neat extension for Firefox called ‘multi-account containers’, with no relation to application containers, but instead are as browser tabs. When I discovered what these container-tabs could do, I was amazed this wasn’t more popular.. It allows individual browser tabs to be their own session or cookie ‘bubble’ enabling separation of work/life/lab/other login sessions within the same Firefox window.

But enough banter about cool browser extensions; if you’ve that or just a series of private/incognito-mode Firefox/Chrome/Edge(?) browser windows, you should test with that. Now test the auth provider login from a state of logged out and with cookies cleared in order to be sure there aren’t cached authentication tokens falsely showing you successful auth to the cluster.

So now that you know how to get users to authenticate via Azure, you’re one step closer to helping someone to leverage the power of enterprise k8s, and it wasn’t that hard now, was it?

Tagged:



//comments


//blog search


//other topics