Enabling the persistent OAuth 2.0 service in WebGUI in a high availability disaster recovery hybrid deployment

WebGUI supports persistence in the OAuth 2.0 service by persisting OAuth tokens and clients in the ObjectServer in a high availability disaster recovery (HADR) hybrid deployment.

Before you begin

Ensure that WebGUI ObjectServer load balancing is set up on each WebGUI node. For more information, see Configuring a load balancing environment external icon in the IBM® Tivoli® Netcool®/OMNIbus documentation.
Note: There are two methods for the OAuth changes. The recommended method is to use the ObjectServer database to create and maintain the OAuth database tables, as described in the following steps. You can also use a Db2® database. For more information, see Setting up persistence for the OAuth service with a Db2 database.

About this task

To enable persistence, complete the following steps on your HADR hybrid deployment.

Procedure

Set up OAuth persistence

  1. Create a table in your primary and backup ObjectServer pair:
    1. Create a new file in the $NCHOME/omnibus/etc/web_oauth.sql file and paste the following content:
      CREATE database OAuthDBSchema;
      go
      
      CREATE TABLE OAuthDBSchema.OAUTH20CACHE persistent
      (
      LOOKUPKEY VARCHAR(256) PRIMARY KEY, 
      UNIQUEID VARCHAR(128) NODEFAULT, 
      COMPONENTID VARCHAR(256) NODEFAULT, 
      TYPE VARCHAR(64) NODEFAULT, 
      SUBTYPE VARCHAR(64), 
      CREATEDAT UNSIGNED64, 
      LIFETIME INT, 
      EXPIRES UNSIGNED64, 
      TOKENSTRING VARCHAR(2048) NODEFAULT, 
      CLIENTID VARCHAR(64) NODEFAULT, 
      USERNAME VARCHAR(64) NODEFAULT, 
      SCOPE VARCHAR(512) NODEFAULT, 
      REDIRECTURI VARCHAR(2048), 
      STATEID VARCHAR(64) NODEFAULT
      );
      go
      
      CREATE TABLE OAuthDBSchema.OAUTH20CLIENTCONFIG persistent
      (
      COMPONENTID VARCHAR(256) PRIMARY KEY, 
      CLIENTID VARCHAR(256) PRIMARY KEY, 
      CLIENTSECRET VARCHAR(256), 
      DISPLAYNAME VARCHAR(256) NODEFAULT, 
      REDIRECTURI VARCHAR(2048), 
      ENABLED INT
      );
      go
    2. Add the table to the primary (AGG_P) ObjectServer, by running the following command:
      $NCHOME/omnibus/bin/nco_sql -user root -password <password> -server AGG_P -input $NCHOME/omnibus/etc/web_oauth.sql
    3. Add the table to the backup (AGG_B) ObjectServer, by running the following command:
      $NCHOME/omnibus/bin/nco_sql -user root -password <password> -server AGG_B -input $NCHOME/omnibus/etc/web_oauth.sql
  2. Add the following section to the $NCHOME/omnibus/etc/AGG_GATE.map file:
    ###############################################################################
    #
    # WebGUI & WAS OAUTH20 Persistence Service on ObjectServer
    #
    ###############################################################################
    CREATE MAPPING Oauth20CacheMap
    (
    'LOOKUPKEY' = '@LOOKUPKEY' ON INSERT ONLY,
    'UNIQUEID' = '@UNIQUEID',
    'COMPONENTID' = '@COMPONENTID',
    'TYPE' = '@TYPE',
    'SUBTYPE' = '@SUBTYPE',
    'CREATEDAT' = '@CREATEDAT',
    'LIFETIME' = '@LIFETIME',
    'EXPIRES' = '@EXPIRES',
    'TOKENSTRING' = '@TOKENSTRING',
    'CLIENTID' = '@CLIENTID',
    'USERNAME' = '@USERNAME',
    'SCOPE' = '@SCOPE',
    'REDIRECTURI' = '@REDIRECTURI',
    'STATEID' = '@STATEID'
    );CREATE MAPPING Oauth20ClientConfig
    (
    'COMPONENTID' = '@COMPONENTID' ON INSERT ONLY,
    'CLIENTID' = '@CLIENTID' ON INSERT ONLY,
    'CLIENTSECRET' = '@CLIENTSECRET',
    'DISPLAYNAME' = '@DISPLAYNAME',
    'REDIRECTURI' = '@REDIRECTURI',
    'ENABLED' = '@ENABLED'
    );
  3. Add the following section to the $NCHOME/omnibus/etc/AGG_GATE.tblrep.def file:
    ###############################################################################
    #
    # WebGUI & WAS OAUTH20 Persistence on ObjectServer
    #
    ###############################################################################
    REPLICATE ALL FROM TABLE 'OAuthDBSchema.OAUTH20CACHE'
    USING map 'Oauth20CacheMap';
    
    REPLICATE ALL FROM TABLE 'OAuthDBSchema.OAUTH20CLIENTCONFIG'
    USING map 'Oauth20ClientConfig';
  4. Restart the Netcool/OMNIbus gateway.
  5. Create a WebSphere® Application Server data source for OAUTH persistence.
    1. Log on to the WebSphere Application admin console.
    2. Create an authentication alias. Click WAS Admin Console > Security > Global Security > Java Authentication and Authorization Service > J2C authentication data. Click New, provide an alias name, provide your ObjectServer credentials, and click Apply.
    3. Click WAS Admin Console > Resources > JDBC > Data source > New....
    4. Set the data source name to OAuthProvider.
    5. Set the JNDI name to jdbc/oauthProvider
    6. Click Next.
    7. Create a new JDBC provider.
    8. Click Next.
    9. Select Sybase for the database type.
    10. Select Sybase JDBC 3 Driver for the provider type.
    11. Select Connection pool data source for the implementation type.
    12. Set the name to Sybase JDBC 3 Driver OAuth.
    13. Click Next.
    14. Set the class path to ${SYBASE_JDBC_DRIVER_PATH}/jconn3.jar.
    15. Provide the path to the JAZZSM_HOME/lib/OServer directory, for example /opt/IBM/JazzSM/lib/OServer.
    16. Click Next.
    17. Provide the port number of the ObjectServer.
    18. Provide the ObjectServer server host name.
    19. Set the database name to OAuthDBSchema.
    20. Click Next.
    21. Select the authentication alias, which was created earlier as part of the HA on ObjectServer prerequisite for component-managed authentication alias.
    22. Click Next.
    23. Click Finish and Save link.

Update the OAuth settings

  1. Create or replace the JAZZSM_HOME/profile/config/cells/JazzSMNode01Cell/oauth20/NetcoolOAuthProvider.xml file with the following content:
    <?xml version="1.0" encoding="UTF-8"?>
    <OAuthServiceConfiguration>
    
      <!-- Example parameters for JDBC database stores -->
              <parameter name="oauth20.client.provider.classname" type="cc" customizable="false">
                <value>com.ibm.ws.security.oauth20.plugins.db.CachedDBClientProvider</value>
              </parameter>
              <parameter name="oauth20.token.cache.classname" type="cc" customizable="false">
                <value>com.ibm.ws.security.oauth20.plugins.db.CachedDBTokenStore</value>
              </parameter>
          <parameter name="oauth20.client.cache.seconds" type="cc" customizable="true">
                <value>600</value>
              </parameter>
              <parameter name="oauthjdbc.JDBCProvider" type="ws" customizable="false">
                <value>jdbc/oauthProvider</value>
              </parameter>
              <parameter name="oauthjdbc.client.table" type="ws" customizable="false">
                <value>OAuthDBSchema.OAUTH20CLIENTCONFIG</value>
              </parameter>
              <parameter name="oauthjdbc.token.table" type="ws" customizable="false">
                <value>OAuthDBSchema.OAUTH20CACHE</value>
              </parameter>
              <parameter name="oauthjdbc.CleanupInterval" type="ws" customizable="true">
                <value>3600</value>
              </parameter>
              <parameter name="oauthjdbc.CleanupBatchSize" type="ws" customizable="true">
                <value>250</value>
              </parameter>
          <parameter name="oauthjdbc.AlternateSelectCountQuery" type="ws" customizable="false">
            <value>false</value>
          </parameter>
              <parameter name="oauth20.db.token.cache.jndi.tokens" type="ws" customizable="false">
                <value>services/cache/OAuth20DBTokenCache</value>
              </parameter>
              <parameter name="oauth20.db.token.cache.jndi.clients" type="ws" customizable="false">
                <value>services/cache/OAuth20DBClientCache</value>
              </parameter>
      
      <parameter name="oauth20.max.authorization.grant.lifetime.seconds" type="cc" customizable="true">
        <value>604800</value>
      </parameter>
      <parameter name="oauth20.code.lifetime.seconds" type="cc" customizable="true">
        <value>60</value>
      </parameter>
      <parameter name="oauth20.code.length" type="cc" customizable="true">
        <value>30</value>
      </parameter>
      <parameter name="oauth20.token.lifetime.seconds" type="cc" customizable="true">
        <value>3600</value>
      </parameter>
      <parameter name="oauth20.access.token.length" type="cc" customizable="true">
        <value>40</value>
      </parameter>
      <parameter name="oauth20.issue.refresh.token" type="cc" customizable="true">
        <value>true</value>
      </parameter>
      <parameter name="oauth20.refresh.token.length" type="cc" customizable="true">
        <value>50</value>
      </parameter>
      <parameter name="oauth20.access.tokentypehandler.classname" type="cc" customizable="false">
        <value>com.ibm.ws.security.oauth20.plugins.BaseTokenHandler</value>
      </parameter>
      <parameter name="oauth20.mediator.classnames" type="cc" customizable="false">
      </parameter>
      <parameter name="oauth20.allow.public.clients" type="cc" customizable="true">
        <value>true</value>
      </parameter>
      <parameter name="oauth20.grant.types.allowed" type="cc" customizable="false">
        <value>authorization_code</value>
        <value>refresh_token</value>
        <value>password</value>
      </parameter>
      <parameter name="oauth20.authorization.form.template" type="cc" customizable="true">
        <value>template.html</value>
      </parameter>
      <parameter name="oauth20.authorization.error.template" type="cc" customizable="true">
        <value></value>
      </parameter>
      <parameter name="oauth20.authorization.loginURL" type="cc" customizable="true">
        <value>login.jsp</value>
      </parameter>
      <!-- Optional audit handler, uncomment or add a plugin to enable
              <parameter name="oauth20.audithandler.classname" type="cc" customizable="true">
                    <value>com.ibm.oauth.core.api.audit.XMLFileOAuthAuditHandler</value>
              </parameter>
              <parameter name="xmlFileAuditHandler.filename" type="cc" customizable="true">
                    <value>D:\oauth20Audit.xml</value>
              </parameter>
      -->
    
      <!-- Parameters for TAI configuration. These can optionally be added as TAI Custom properties instead, which gives more flexibility.
                      Additional custom TAI properties can be added as parameters by specifying type="tai"
      -->
              <parameter name="filter" type="tai" customizable="true">
          <value>request-url%=ibm/console</value>
              </parameter>
    
              <parameter name="oauthOnly" type="tai" customizable="true">
                <value>false</value>
              </parameter>
    
            <parameter name="oauth20.autoauthorize.param" type="ws" customizable="false">
                <value>autoauthz</value>
              </parameter>
            <parameter name="oauth20.autoauthorize.clients" type="ws" customizable="true">
                <value>hdm-client-id</value>
          <value>debug-client-id</value>
              </parameter>
    
      <!-- mediator for resource owner credential: optional mediator to validate resource owner credential against current active user registry>
      -->
        <parameter name="oauth20.mediator.classnames" type="cc" customizable="true">
                <value>com.ibm.ws.security.oauth20.mediator.ResourceOwnerValidationMedidator</value>
        </parameter>
    
       <!-- optional limit for the number of tokens a user/client/provider combination can be issued
           <parameter name="oauth20.token.userClientTokenLimit" type="ws" customizable="true">
                <value>100</value>
          </parameter>
       -->
    </OAuthServiceConfiguration>

All nodes

  1. Apply steps 5 and 6 to all WebGUI nodes.
  2. Restart all WebGUI nodes.

Register the OAuth client

  1. Create a new WAAPI XML file, WEBGUI_PRODUCT_HOME/waapi/etc/sample/registOAuthClient.xml, and add the following content:
    <!--
    WAAPI template to register an OAUTH client in the ObjectServer
    All @tokens@ below must be subtistuted
    -->
    
    <methodCall>
    <method methodName="oauth.registerOauthClient">
    <oauth componentId="NetcoolOAuthProvider" clientId="@clientId@" clientSecret="@clientSecret@" displayName="hdm-client" redirectUri="@redirectUri@" enabled="1" /> 
    </method>
    </methodCall>
    1. Run the following command on the NOI cluster to retrieve the clientId value:
      oc get secret <release_name>-was-oauth-cnea-secrets -o json -n dev| grep client-id | cut -d : -f2 | cut -d '"' -f2 | base64 -d;echo
      Replace @client-id@ in the registOAuthClient.xml file with the value returned by the command.
    2. Run the following command on the NOI cluster to retrieve the client-secret value:
      oc get secret <release_name>-was-oauth-cnea-secrets -o json -n dev| grep client-secret | cut -d : -f2 | cut -d '"' -f2 | base64 -d;echo
      Replace @client-secret@ in the registOAuthClient.xml file with the value returned by the command.
    3. Replace @redirectUri@in the registOAuthClient.xml file with the following value:
      https://netcool-<release_name>.apps.<fqdn>/users/api/authprovider/v1/was/return
      Where; <release_name> is the name of your deployment, as specified by the value used for name (OLM UI Form view), or name in the metadata section of the noi.ibm.com_noihybrids_cr.yaml or noi.ibm.com_nois_cr.yaml files (YAML view), and <fqdn> is the cluster FQDN.
  2. Register the OAuth client with the following command:
    <WEBGUI_PRODUCT_HOME>/waapi/bin/waapi/runwaapi -username smadmin -password <password> -file ../etc/samples/registOAuthClient.xml