Configure single sign-on (SSO) for WebSphere Liberty operators

An administrator can configure single sign-on (SSO) for WebSphere Liberty operators to authenticate and manage users. Authentication can be delegated to external providers, such as Google, Facebook, LinkedIn, Twitter, GitHub, or any OpenID Connect (OIDC) or OAuth 2.0 clients.

  1. Configure and build the application image with single sign-on. Follow the instructions in Moving applications to containers and Configure single sign-on (SSO) for applications in containers.
  2. Complete one of these choices to configure SSO in your operator.


Configure SSO with specified client IDs and secrets

The operator can specify a client ID and secret in advance. A disadvantage to this configuration is that the client ID and secret must be supplied for registration repetitively, rather than automatically with the provider administrator supplying the information needed for registration one time.

  1. Create a secret that specifies sensitive information such as client IDs, client secrets, and tokens for the login providers you selected in application image.

    Create the Secret named WebSphereLibertyApplication_name-wlapp-sso in the same namespace as the WebSphereLibertyApplication instance. In the following sample snippets, WebSphereLibertyApplication is named my-app, so the secret must be named my-app-wlapp-sso. Both are in the same namespace called demo.

    The keys within the Secret must follow the provider_name-sensitive_field_name naming pattern. For example, google-clientSecret. Instead of a - character in between, we can also use . or _. For example, oauth2_userApiToken.

      apiVersion: v1
      kind: Secret
      metadata:
        # Name of the secret should be in this format: <WebSphereLibertyApplication_name>-wlapp-sso
        name: my-app-wlapp-sso
        # Secret must be created in the same namespace as the WebSphereLibertyApplication instance
        namespace: demo
      type: Opaque
      data:
        # The keys must be in this format: <provider_name>-<sensitive_field_name>
        github-clientId: bW9vb29vb28=
        github-clientSecret: dGhlbGF1Z2hpbmdjb3c=
        twitter-consumerKey: bW9vb29vb28=
        twitter-consumerSecret: dGhlbGF1Z2hpbmdjb3c=
        oidc-clientId: bW9vb29vb28=
        oidc-clientSecret: dGhlbGF1Z2hpbmdjb3c=
        oauth2-clientId: bW9vb29vb28=
        oauth2-clientSecret: dGhlbGF1Z2hpbmdjb3c=
        oauth2-userApiToken: dGhlbGF1Z2hpbmdjb3c=

    The operator watches for the creation and deletion of the SSO secret and any updates to it. Adding, updating, or removing keys from the secret are passed down to the application automatically.

  2. Configure single sign-on in the WebSphereLibertyApplication custom resource (CR). At minimum, set the .spec.sso: {} field so that the operator can pass the values from the secret to the application. Refer to the WebSphereLibertyApplication CR for more SSO configurations.

  3. Configure secured Service and secured Route with necessary certificates. Refer to Certificates for more information.

  4. To automatically trust certificates from popular identity providers, including social login providers such as Google and Facebook, set the SEC_TLS_TRUSTDEFAULTCERTS environment variable to true. To automatically trust certificates issued by the Kubernetes cluster, set environment variable SEC_IMPORT_K8S_CERTS to true. Alternatively, we can include the necessary certificates manually when building application image or mounting them using a volume when you deploy the application.

      apiVersion: liberty.websphere.ibm.com/v1
      kind: WebSphereLibertyApplication
      metadata:
        name: my-app
        namespace: demo
      spec:
        applicationImage: quay.io/my-repo/my-app:1.0
        env:
          - name: SEC_TLS_TRUSTDEFAULTCERTS
            value: "true"
          - name: SEC_IMPORT_K8S_CERTS
            value: "true"
        sso:
          redirectToRPHostAndPort: https://redirect-url.mycompany.com
          github:
            hostname: github.mycompany.com
          oauth2:
            - authorizationEndpoint: specify-required-value
              tokenEndpoint: specify-required-value
          oidc:
            - discoveryEndpoint: specify-required-value
        service:
          certificateSecretRef: mycompany-service-cert
          port: 9443
          type: ClusterIP
        expose: true
        route:
          certificateSecretRef: mycompany-route-cert
          termination: reencrypt


Configure SSO automatic registration with OIDC providers

The operator can request a client ID and client secret from providers, rather than requiring them in advance. This ability can simplify deployment, as the provider administrator can supply the information that is needed for registration one time, instead of supplying client IDs and secrets repetitively. The callback URL from the provider to the client is supplied by the operator, so doesn't need to be known in advance.

  1. Add attributes that are named provider_name-autoreg-field_name to the Kubernetes secret.

    First, the operator makes an https request to the .spec.sso.oidc[].discoveryEndpoint field to obtain URLs for subsequent REST calls. Next, it makes other REST calls to the provider and obtains a client ID and client secret. The Kubernetes secret is updated with the obtained values.

  2. For Red Hat Single Sign-on (RH-SSO), we can set the .spec.sso.oidc[].userNameAttribute field to preferred_username to obtain the user ID that was used to log in. For IBM Security Verify, set the field to given_name.

    The following example secret is tested on Red Hat OpenShift with RH-SSO and IBM® Security Verify.

      apiVersion: v1
      kind: Secret
      metadata:
        # Name of the secret should be in this format: <WebSphereLibertyApplication_name>-wlapp-sso
        name: my-app-wlapp-sso
        # Secret must be created in the same namespace as the WebSphereLibertyApplication instance
        namespace: demo
      type: Opaque
      data:
        # base64 encode the data before entering it here.
        #
        # Leave the clientId and secret out, registration will obtain them and update their values.
        # oidc-clientId
        # oidc-clientSecret
        #
        # Reserved: <provider>-autoreg-RegisteredClientId and RegisteredClientSecret
        # are used by the operator to store a copy of the clientId and clientSecret values.
        #
        # Automatic registration attributes have -autoreg- after the provider name.
        #
        # Red Hat Single Sign On requires an initial access token for registration.
        oidc-autoreg-initialAccessToken: xxxxxyyyyy
        #
        # IBM Security Verify requires a special clientId and clientSecret for registration.
        # oidc-autoreg-initialClientId: bW9vb29vb28=
        # oidc-autoreg-initialClientSecret: dGhlbGF1Z2hpbmdjb3c=
        #
        # Optional: Grant types are the types of OAuth flows the resulting clients will allow
        # Default is authorization_code,refresh_token. Specify a comma separated list.
        # oidc-autoreg-grantTypes: base64 data goes here
        #
        # Optional: Scopes limit the types of information about the user that the provider will return.
        # Default is openid,profile. Specify a comma-separated list.
        # oidc-autoreg-scopes: base64 data goes here
        #
        # Optional: To skip TLS certificate checking with the provider during registration, specify insecureTLS as true. 
        # Default is false.
        # oidc-autoreg-insecureTLS: dHJ1ZQ==


Configure multiple OIDC and OAuth 2.0 providers

We can authenticate with multiple OIDC and OAuth 2.0 providers.

  1. Configure and build application image with multiple OIDC or OAuth 2.0 providers.

    For example, set the provider name in your Dockerfile. The provider name must be unique and must contain only alphanumeric characters.

      ARG SEC_SSO_PROVIDERS="google oidc:provider1,provider2 oauth2:provider3,provider4"

  2. Use the provider name in an SSO Secret to specify its client ID and secret.

    For example, the following Secret sets provider1-clientSecret: dGhlbGF1Z2hpbmdjb3c= for a client ID and secret.

      apiVersion: v1
      kind: Secret
      metadata:
        # Name of the secret should be in this format: <WebSphereLibertyApplication_name>-wlapp-sso
        name: my-app-wlapp-sso
        # Secret must be created in the same namespace as the WebSphereLibertyApplication instance
        namespace: demo
      type: Opaque
      data:
        # The keys must be in this format: <provider_name>-<sensitive_field_name>
        google-clientId: xxxxxxxxxxxxx
        google-clientSecret: yyyyyyyyyyyyyy
        provider1-clientId: bW9vb29vb28=
        provider1-clientSecret: dGhlbGF1Z2hpbmdjb3c=
        provider2-autoreg-initialClientId: bW9vb29vb28=
        provider2-autoreg-initialClientSecret: dGhlbGF1Z2hpbmdjb3c=
        provider3-clientId: bW9vb29vb28=
        provider3-clientSecret: dGhlbGF1Z2hpbmdjb3c=
        provider4-clientId: bW9vb29vb28=
        provider4-clientSecret: dGhlbGF1Z2hpbmdjb3c=

  3. Configure a field for each corresponding provider in the WebSphereLibertyApplication CR. Use one or both of the .spec.sso.oidc[].id and .spec.sso.oauth2[].id fields.

      sso:
        oidc:
          - id: provider1
            discoveryEndpoint: specify-required-value
          - id: provider2
            discoveryEndpoint: specify-required-value
        oauth2:
          - id: provider3
            authorizationEndpoint: specify-required-value
            tokenEndpoint: specify-required-value
          - id: provider4
            authorizationEndpoint: specify-required-value
            tokenEndpoint: specify-required-value