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.
-
To set the provider URL before installing the IAM service, see Authentication settings.
-
To set the provider URL after you installed the IAM service, add the URL to the
platform-auth-idp
configmap.-
Open the configmap for editing.
oc edit cm platform-auth-idp -n ibm-common-services
-
Update the
PROVIDER_ISSUER_URL: ""
parameter.PROVIDER_ISSUER_URL: <https://<hostname>:443/idprovider/v1/auth/.well-known/openid-configuration>
-
Save and exit the configmap.
-
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:
- An authorized client of your product authentication service
- The authentication service knows where to redirect requests for this client after a successful authentication
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:
- Automated client registration method 1 - by using Helm chart
- Automated client registration method 2 - by using a script
- Automated client registration method 3 - by using a CustomResourceDefinition (CRD)
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).
-
Install
cloudctl
. For more information, see Installing IBM Cloud Pak CLI (cloudctl). -
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"] }
-
Create the customized version of your
registration.json
content by editing the sample content. Thewlp_client_id
andwlp_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 }}
-
Register a client with your product authentication service.
cloudctl iam oauth-client-register -f registration.json
Onboard by using IAM
-
Install
kubectl
. For more information, see Installing the Kubernetes CLI (kubectl). -
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)
-
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"] }
-
Create the customized version of your
regisration.json
content by editing the sample content. Thewlp_client_id
andwlp_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 }}
-
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:
https://<cluster_address>:443/idprovider/v1/info
https://<cluster_address>:443/idprovider/v1/auth/identitytoken
https://<cluster_address>:443/idprovider/v1/auth/token
https://<cluster_address>:443/idprovider/v1/auth/authorize
https://<cluster_address>:443/idprovider/v1/auth/userInfo
https://<cluster_address>:443/idprovider/v1/auth/introspect
https://<cluster_address>:443/idprovider/v1/auth/.well-known/openid-configuration
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:
-
Call to the
/authorize
endpoint withclient_id
,scope
,redirect_uri
, andgrant_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+profileclient_id
: The unique ID that is used to recognize a service withresponse_type
: coderedirect_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 withresponse_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
- Following are the default parameters:
-
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 IDclient_secret
: The service client secretscope
: openidredirect_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,
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:
{}