Overview

Skill Level: Intermediate

This recipe demonstrates how to enable user authentication for an application on IBM Cloud Private.

Ingredients

1. You need to have access to IBM Cloud Private cluster, version 3.1.1 or above. It is preferred to set your IBM Cloud Private cluster to connect to a directory server.

2. Obtain the client registration secret from a user who has administrator access to the `kube-system` namespace. Get the registration secret by running the following command:

export OAUTH2_CLIENT_REGISTRATION_SECRET=$(kubectl -n kube-system get secret platform-oidc-credentials -o yaml | grep OAUTH2_CLIENT_REGISTRATION_SECRET | awk '{ print$2}' | base64 --decode)

Step-by-step

  1. Register the application as the OIDC client

    1. Create a file named `registration.json` by using the following template:

    {
       “token_endpoint_auth_method”: “client_secret_basic”,
       “client_id”: “”,
       “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”: [
           <url you want to redirect to direct to after logout; that is “https://example.abc.com”>
       ],
       “preauthorized_scope”: “openid profile email general”,
       “introspect_tokens”: true,
       “trusted_uri_prefixes”: [
           <A trusted url, that is IBM Cloud Private cluster “https://<IBM_Cloud_Private_endpoint>:<port>”>
       ],
       “redirect_uris”: [
           <the callback URL that IBM Cloud Private OIDC service can call upon; that is “https://example.abc.com/auth/liberty/callback”>
       ]}

    2. Define the redirected URL for your application logout page. This is the URL for your application’s landing page after the user is logged on. Edit post_logout_redirect_uris field in your JSON file to add the actual URL: 

        “post_logout_redirect_uris”: [“https://example.abc.com”]

    3. Define the trusted URL prefixes for your application. Edit trusted_uri_prefixes field in your JSON file to add the actual URL:

        “trusted_uri_prefixes”: [“https://<IBM_Cloud_Private_endpoint>:<port>”] 

    4. Define the callback URL for your application. This is the URL where the identity authentication manager sends the response. Edit redirect_uris field in your JSON file to add the actual URL:

        ”redirect_uris”: [“https://<example.abc.com>:<port>/auth/liberty/callback]

    5. Register your application by running the following command:  

        curl -i -k -X POST -u oauthadmin:$OAUTH2_CLIENT_REGISTRATION_SECRET -H “Content-Type: application/json” –data @registration.json https://<IBM_Cloud_Private_IP>:<port>/idauth/oidc/endpoint/OP/registration

    Note: Your output includes the generated client ID and client secret if it is not specified in the registration file.

  2. Add the login and logout flow for your application

    1. Create a `GET` request with the OIDC authorization endpoint for your application. Your `GET` request should resemble the following example:

    GET https://<IBM_Cloud_Private_IP>:<port>/v1/auth/authorize?
           response_type=code&
           scope=openid email&
           client_id=client01&
           redirect_uri=https://<example.abc.com>:<port>/auth/liberty/callback

    Upon receiving the request, the authorization endpoint redirects the browser to the IBM Cloud Private login page, where the user can submit the user ID and password for authentication. Once the authentication is successful, the authorization endpoint sends back an authorization code and redirects the browser to the application callback endpoint:

    GET https://<example.abc.com>:<port>/auth/liberty/callback?code=jtcs6gIVyoZAMp8LeOgbHCkBj04qcu

    2. Implement the callback endpoint to handle the `GET` request. The endpoint extracts the authorization code, and invokes the IBM Cloud Private OIDC token endpoint. View the following token request example:

    POST https://<IBM_Cloud_Private_IP>:<port>/v1/auth/token
        -d ‘{“code”: “jtcs6gIVyoZAMp8LeOgbHCkBj04qcu” ,
          “redirect_uri”: “https://<example.abc.com>:<port>/auth/liberty/callback”,
          “grant_type”: “authorization_code”,
          “client_id”: “client01”,
          “client_secret”: “qefcvkererqg”}’

    The token endpoint responds with an access token and ID token. Your output might resemble the following response:

    HTTP/1.1 200 OK
    Content-Type: application/json
    {
        “access_token”:<access_token>,
        “token_type”:”Bearer”,
        “expires_in”:3600,
        “id_token”: <id_token>
    }

    Your application login flow is complete. The ID token carries the user identity information. The access token can be used to grant access. Many IBM Cloud Private APIs require access tokens to be included in the authorization header.

    3. Implement the logout flow for your application. You must invalidate the user session and redirect them to the IBM Cloud Private logout URL. Your URL might resemble the following example. The login_uri is where you want the application lands after the logout.

    https://<IBM_Cloud_Private_IP>:<port>/v1/auth/logout?login_url=https://<example.abc.com>:<port>/logout

2 comments on"Enabling user authentication to an application with IBM Cloud Private IAM"

  1. Hi Xiaoyan Zhang, Can you provide the sample source code you used for step 2 “Add the login and logout flow for your application”?

    • See the following example that uses NodeJS Express application. The application uses an OIDC strategy library.

      var express = require(‘express’);
      var router = express.Router();
      var passport = require(‘passport’);
      var OpenIDConnectStrategy = require(‘../utils/passport-icp-oidc/lib/index’).ICPOIDCStrategy;
      var Strategy = new OpenIDConnectStrategy({
      authorizationURL : authorization_url,
      tokenURL : token_url,
      clientID : client_id,
      scope: ’email’,
      response_type: ‘code’,
      clientSecret : client_secret,
      callbackURL : callback_url,
      skipUserProfile: true,
      CACertPathList: [‘/iam-cert.pem’],
      issuer: issuer_id},
      function(iss, sub, profile, accessToken, done) {
      process.nextTick(function() {
      profile.accessToken = accessToken;
      profile.refreshToken = refreshToken;
      done(null, profile);
      })
      }
      );
      passport.use(Strategy);

      The strategy requires several parameters. You can customize the following parameters:
      authorizationURL: The identity service authorization endpoint, which is https://:/idprovider/v1/auth/authorize.
      tokenURL: The identity service token endpoint, which is https://:/idprovider/v1/auth/token.
      clientID: The client ID from your OIDC registration.
      clientSecret: The client secret from your OIDC registration.
      callbackURL: This parameter must match the callback URI that is defined in your OIDC registration. For example, https://myapp.example.com:30001/api/auth/callback.
      CACertPathList: This list can include the CA certificate and the signing certificate of your token for secure connection with your common services cluster.
      issuer: The issuer ID must match the iss in the ID token.

Join The Discussion