Authentication onboarding and single sign-on

You can onboard workloads to Identity and Access Management (IAM) and configure single sign-on (SSO).

Onboarding is the configuration of workloads in your product IAM. You can configure your workloads to obtain the authentication and authorization service requirements. As part of this process, the workloads must make themselves be known to IAM as a service by registering themselves with the authentication and the authorization services.

The information in the following sections uses <cluster_address>, which is the IBM Cloud Pak console route. You can get the IBM Cloud Pak console route by running the following command:

oc -n ibm-common-services get route cp-console -o yaml

The IBM Cloud Pak console route is in the spec.host section.

Customizing the authentication URL

Default configuration of OpenID Connect (OIDC) in your product uses <cluster_address>:443 in the authentication endpoints, which are used to authenticate users to Kubernetes. However, in the oidcIssuerURL, local host IP address is used, the default value of which is https://127.0.0.1:443/idauth/oidc/endpoint/OP. If required, you can change the oidcIssuerURL endpoint to use a hostname for Kubernetes authentication. For more information, see Authentication settings.

Customizing the OIDC provider URL

The .well-known/openid-configuration endpoint provides configuration information about the OIDC provider. The provider URL is set to an empty value by default.

For the API, see OIDC Registration APIs.

Onboarding a workload

The first step towards onboarding the workload to the authentication service of your product is to register itself as a client of the authentication service based on Liberty. The registration is an important step because it is through this registration that your product authentication service knows the following information about the workload:

Most of the content workloads have a login page of their own and would want to redirect to their service-specific dashboard page after a successful login.

The OpenID Connect (OIDC) Client Registration process requires access to a secret that is in the ibm-common-services namespace. You can view the OAUTH2_CLIENT_REGISTRATION_SECRET from the Kubernetes secret platform-oidc-credentials. The following methods are available for obtaining the OAuth secret and for automatic registration:

To manually onboard, that is obtain the secret and register the client, use the cloudctl or IAM APIs.

Onboard by using cloudctl

For more information about the cloudctl IAM commands, see cloudctl iam commands (iam).

  1. Install cloudctl. For more information, see Installing IBM Cloud Pak CLI (cloudctl).

  2. Construct the client registration payload. Following is a sample content from the registration.json file:

      {
      "token_endpoint_auth_method":"client_secret_basic",
      "client_id": "<WLP_CLIENT_ID>",
      "client_secret": "<WLP_CLIENT_SECRET>",
      "scope":"openid profile email",
      "grant_types":[
         "authorization_code",
         "client_credentials",
         "password",
         "implicit",
         "refresh_token",
         "urn:ietf:params:oauth:grant-type:jwt-bearer"
      ],
      "response_types":[
         "code",
         "token",
         "id_token token"
      ],
      "application_type":"web",
      "subject_type":"public",
      "post_logout_redirect_uris":[
         "https://<ICP_PROXY_IP>:<PORT_WHERE_SERVICE_RUNS>"   ],
      "preauthorized_scope":"openid profile email general",
      "introspect_tokens":true,
      "trusted_uri_prefixes":[
         "https://<ICP_ENDPOINT>:<port>", "https://<ICP_PROXY_IP>"    ],
      "redirect_uris":["https://<ICP_PROXY_IP>:<PORT_WHERE_SERVICE_RUNS>/auth/liberty/callback"]
      }
    
  3. Create the customized version of your registration.json content by editing the sample content. The wlp_client_id and wlp_client_secret can be generated by the content service. Your output might resemble the following code:

    wlp_client_id: {{ randAlphaNum 32 | b64enc | quote }}
    wlp_client_secret: {{ randAlphaNum 32 | b64enc | quote }}
    
  4. Register a client with your product authentication service.

     cloudctl iam oauth-client-register -f registration.json
    

Onboard by using IAM

  1. Install kubectl. For more information, see Installing the Kubernetes CLI (kubectl).

  2. Obtain the OAUTH secret:

     OAUTH2_CLIENT_REGISTRATION_SECRET=$(kubectl -n ibm-common-services get secret platform-oidc-credentials -o "jsonpath={.data.OAUTH2_CLIENT_REGISTRATION_SECRET}" | base64 --decode)
    
  3. Construct the client registration payload. Following is a sample content from the registration.json file:

      {
      "token_endpoint_auth_method":"client_secret_basic",
      "client_id": "<WLP_CLIENT_ID>",
      "client_secret": "<WLP_CLIENT_SECRET>",
      "scope":"openid profile email",
      "grant_types":[
         "authorization_code",
         "client_credentials",
         "password",
         "implicit",
         "refresh_token",
         "urn:ietf:params:oauth:grant-type:jwt-bearer"
      ],
      "response_types":[
         "code",
         "token",
         "id_token token"
      ],
      "application_type":"web",
      "subject_type":"public",
      "post_logout_redirect_uris":[
         "https://<ICP_PROXY_IP>:<PORT_WHERE_SERVICE_RUNS>"   ],
      "preauthorized_scope":"openid profile email general",
      "introspect_tokens":true,
      "trusted_uri_prefixes":[
         "https://<ICP_ENDPOINT>:<port>", "https://<ICP_PROXY_IP>"    ],
      "redirect_uris":["https://<ICP_PROXY_IP>:<PORT_WHERE_SERVICE_RUNS>/auth/liberty/callback"]
      }
    
  4. Create the customized version of your regisration.json content by editing the sample content. The wlp_client_id and wlp_client_secret can be generated by the content service. Your output might resemble the following code:

     wlp_client_id: {{ randAlphaNum 32 | b64enc | quote }}
     wlp_client_secret: {{ randAlphaNum 32 | b64enc | quote }}
    
  5. Register a client with the authentication service. Run the following API command from any node that has access to the master node:

     curl -i -k -X POST -u oauthadmin:$OAUTH2_CLIENT_REGISTRATION_SECRET -H "Content-Type: application/json" --data @platform-oidc-registration.json https://<cluster_address>:443/idauth/oidc/endpoint/OP/registration
    

Authentication enforcement by workloads

After you register the content service as a client of your product authentication service, you can use the OIDC authentication endpoints to enforce authentication. Your product supports two authentication protocols: OIDC and Security Assertion Markup Language (SAML). The OIDC-based authentication service is the default service in your product. If required, you can be configure a SAML server to provide federated authentication.

OIDC and SAML are both used for single-sign on with your product, but for different purposes.

Your product is an OIDC identity provider and provides authentication and authorization services to your product console and APIs. It works along with one or more Lightweight Directory Access Protocol (LDAP) providers to authenticate the user ID and password with the LDAP service. It provides an access token for subsequent requests to your product services. Your product is an identity provider through LDAP.

You can configure your product as a SAML service provider to allow federated authentication with an external SAML 2.0 identity provider. When you log in to the console, your browser is redirected to the third-party party login page and OIDC issues a bearer token to you.

The following endpoints can be used to enforce authentication for both the OIDC-based and SAML-based authentication services:

OIDC Endpoints for Authentication

Your product provides OIDC-based authentication through WebSphere Liberty server. The IAM authentication micro service manages the OIDC authentication. This authentication is backed by the Liberty-based OIDC server for providing local and LDAP directory-based authentication.

Your product supports the following standard OIDC APIs:

The https://<cluster_address>:443/idprovider/v1/auth/token returns an encrypted token and can be used for all APIs of your product.

For more information about the APIs, see OIDC Registration APIs.

UI authentication - OAUTH Dance implementation

OAuth Dance is an authentication process that identifies users who use OAuth. It follows a two-step process:

  1. Call to the /authorize endpoint with client_id, scope, redirect_uri, and grant_type. The /authorize endpoint presents a login page where you can enter your user name and password. On successful authentication, a code is returned.

    • Following are the default parameters:
      • scope: openid+email+profile
      • client_id: The unique ID that is used to recognize a service with
      • response_type: code
      • redirect_uri: https://ip:port/callback. The URL to which the user is redirected after successfully authentication. In an OAuth dance, the call to the /authorize endpoint is with response_type value equal to the code.
    • Following is an example of the authorize endpoint that calls your product console login page:
       GET https://<cluster_address>/idprovider/v1/auth/authorize?client_id=client_id&scope=openid&redirect_uri=redirect_uri&response_type=code&state=state
      
  2. After the user is authenticated, the OIDC server returns a code. The service that runs on the redirect_uri and listens on this URL, retrieves the code, https://ip:port/callback?code=xvcbdb, and calls the /token endpoint to retrieve the token. Following are the default parameters:

    • client_id: The service client ID
    • client_secret: The service client secret
    • scope: openid
    • redirect_uri: https://ip:port/callback
    • grant_type: authorization_code

The /authorize endpoint from the list of OIDC APIs can be used by the content service for its user interface based login. This API requires the client ID and secret to be passed to your product authentication service to make out where the user must be redirected to after a successful authentication. These URIs are the redirect_uris that are specified during the client registration process.

The redirect_uris is the callback that the Liberty server can call for completing the OAUTH Dance. This callback URL of the content service must take the authorization code and then send the /token request to get the valid access tokens. With these tokens set in the session, the content service can forward the request to the intended page on its service from successful authentication.

CLI authentication

Your product supports CLI-based authentication. If you are running sidecar applications and want to use your product security features for authentication, you can use the following APIs by running the Curl commands:

Authenticate by using your username and password

curl -k -X POST -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
-d "grant_type=password&client_id=<ID>&client_secret=<secret>&username=admin&password=admin&scope=openid" \
https://<cluster_address>/idprovider/v1/auth/identitytoken --insecure

Where, is defined in Foundational service endpoint.

Following is a sample output:

{
  "access_token": "38400d87f39a7c328a4605265eb601bebd9426e2ef6f1b51a449da6a9cb08e03543857ac4ffbd7d2c259867c89324563c5a89f026683aca9262858ae7ffb1e635242eabab3d579793e8f9da09070708dccf2a8d660f3be06550f02af681d2fa64562fb9dc3df1b19839a5d3933311f89348634fa6908fa7d2d50584ffd36f9dc298a3411d3f5abad5c7f45283428ecf0de249eac5534136c31317493f85363126bfe9a6f582403c34a3dab96e3e7bba83c263f1a4ff8d8609fca888852e097e3bc382b822576a53e55e6753c57f79d5703cf6b6bed4b015702ce3ce1636fd834944231fa77eb90079bca398be511f22fd58792a3766a100af10f274e6b9d75a2be2fe6ab18a3ce2ed0c8da7542e0b79f08e32a9ddced6a389572e6247230e1b62adf5fb0ee6549c06f99b85afc7cccd7a51012dea5df40fc27a934be37e9465ddb46a4f43ec542faecb4e6dd062189392b802b8a0ad8c38a00a14f7b9625bcdab251b87cd478c0e5d3c79f8887797da767f209f5fb2b3d44c8b051f49c2ed680a14cd15388b545ca573540184bb27be28378dbe0ecbe2d71c0ac3d7365fce5f1948ead1576f444f70c87d7ba89352b0d2b795a11ccc5ad06441c4143a3e78f80316c72110ba7062159f249719c664818befd6514b1526498729fe624852128495a5fa9c57ba8c9386a1040e0bb8013e93a751722de6e85966994cefce4c43066",
  "token_type": "Bearer",
  "expires_in": 43199,
  "scope": "openid",
  "refresh_token": "ryJlHRTJu0ZWgpDm9Ci11YenaPUk2ehZ51p1gAmL2w5VAThuff",
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiNjZrYjBqMTY1NDBuN3ZhZXczem4iLCJyZWFsbU5hbWUiOiJjdXN0b21SZWFsbSIsInVuaXF1ZVNlY3VyaXR5TmFtZSI6ImFkbWluIiwiaXNzIjoiaHR0cHM6Ly9teWNsdXN0ZXIuaWNwOjk0NDMvb2lkYy9lbmRwb2ludC9PUCIsImF1ZCI6IjZhNTVlMWEzZmY1Mjc5NjY2YTBiNmI4NzcxYTViMzEwIiwiZXhwIjoxNTI5MzQzOTM4LCJpYXQiOjE1MjkzMTUxMzgsInN1YiI6ImFkbWluIiwidGVhbVJvbGVNYXBwaW5ncyI6W119.OHZTG7I5SjTk3uHIJsk7zzg5ueQM5fEU9nC11jSvpRw-tm1T-OBqjKHPQ_g-uhmFuuym3hvQcEB-wRQi4NMB_d580eeXHYYl_NiawunkHIl7AISQQetc7HS4U7ZXx3Mc2EmvqyVyo0zSYowGfT6D_X36O_E6Riz-_rrGvc1nrzOdGa8IjJIi_GncSs5IFNUQxtRA9ZwdtIbQcRrSs9B3hPH8sJqUnaZnOjAkctJA8zQY0eV3IAZ4lFc01_hT5DrOdtAiSAQBoakttxbY8iqEaNHAc07wUiN6J4rcgtJE2ZwOZth1D_39KyD5nbRbNO8HJh6hYFcBplFGwp9FDZb27A"
}

This API returns an access_token, id_token, and a refresh_token. The access_token is used for authorization of your product security components that include team, user, user group, service ID, service, API key, and other components. The id_token is used for authorization of Kubernetes components that include pods, daemonsets, services, and other components. The refresh_token can be used to retrieve fresh tokens in case the tokens are expired.

Retrieve a fresh token

curl -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
-d "grant_type=refresh_token&client_id=<ID>&client_secret=<secret>&scope=openid&refresh_token=ryJlHRTJu0ZWgpDm9Ci11YenaPUk2ehZ51p1gAmL2w5VAThuff" \
https://<cluster_address>/idprovider/v1/auth/token --insecure

Following is a sample output:

{
  "access_token": "77f3ea9695e50d147a3081990c331f8ce9baa0b6d02ac4e970c886eabccd7aa7e7f12e1897ceacbdf6bdaf0881ed5a725f214209eb20b9415c2fcf4ad1afb90412a247aeab6ab0e026e08013b8f2b773b5bdb2d8d3c1247e9e7ebeaa8c9c9c66c1e85caf78105e35e934a28f21619bef2ff17cebe75792da86b4a65c19973713559569e92ae6aa86ddb8ee48991c6ced9caf41ae6c3b88f67fcaacf8c2c6af82018b5f55a4e35c1b9026438b690a606de0314bdced35eab21642b4b6c33c5241db457f2564840b9d32c255d0bfa9e4fda176416f7481c205ee98912790a11134597ce7245264669568fd69153a8e2f240df9edb4df3b219e213c3cfb0366713802a9a525fe85c9ec2a8c54ba61b5d845054ff23eb466c990c15dcb025ef320f36bb21ec0d0a412bcdecafba57da6b239891e22c139a7d4057f84fd741215ed5567c3f4b824d9bbfe92d56b77fe1712d35cea60e12f5207b727e3cc658db1b8b5002780049a5faefd8ccc2ccee9100472dfff58978ee3e7303547dc4ea03025275e58ec4e3da8e6ae91939bfb092f1ce78fe2d91124c179f55bda4027957093090c4f47037771e9cacf227867063c909e9aee3bf87140426052821116c6484037822a41f05a0fa565276b5ff1a8a654d3d5d119f6a665469a7591e4ec197d6a90bd586b8b95e227b9869b8654c23c10f78fc6a3fcbbe6d543638f379736193643",
  "token_type": "Bearer",
  "expires_in": 43199,
  "scope": "openid",
  "refresh_token": "5QM3H8fmGjxhPRyYlQ77s4Z5APOHVk5276ItT8q41e2xKNMxF6"
}

Validate tokens

At any point in time, if you want to validate the tokens that you received by using the previous APIs, you can use either user information or introspect call. See the following APIs:

Get user information
export ACCESS_TOKEN=<Your access token>
curl -k -X POST --header "Authorization: Bearer $ACCESS_TOKEN" \
https://<cluster_address>/idprovider/v1/auth/userInfo

Following is a sample output:

{
  "sub":"admin",
  "iss":"https://<cluster_address>:443/oidc/endpoint/OP"
}
Call introspect endpoint
export TOKEN=<your token>
export CLIENT_ID=<client_id>
export CLIENT_SECRET=<client_secret>

Get the basic authorization header by using the following commands:

BASIC_AUTH_HEADER=`echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64 -w 0`
curl -H "Authorization: Basic $BASIC_AUTH_HEADER" -d "token=$TOKEN" https://<cluster_address>/idprovider/v1/auth/introspect

Revoke a token

If you want to revoke a particular token instead of waiting for its expiry, you can use the following API:

export TOKEN=<Your access token here>
export CLIENT_ID=<client_id here>
export CLIENT_SECRET=<client_secret here>

Get the Basic authorization header by using the following commands:

BASIC_AUTH_HEADER=`echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64 -w 0`
curl -k -X POST -H "Authorization: Basic $BASIC_AUTH_HEADER" -d "token_type_hint=access_token&token=$TOKEN" \
https://<cluster_address>/idprovider/v1/auth/revoke

Following is a sample output:

{}