Enabling the persistent OAuth 2.0 service in WebGUI in a hybrid deployment

WebGUI supports persistence in the OAuth 2.0 service by persisting OAuth tokens and clients in the ObjectServer.

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.

About this task

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

Procedure

  1. Create a table in your primary and backup ObjectServer pair:
    1. Create a $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 code to the $NCHOME/omnibus/etc/AGG_GATE.map file for the aggregation layer ObjectServer gateway.
    ###############################################################################
    #
    # 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 code 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 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 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.
  6. 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>
    Note: Set the client-id values for the oauth20.autoauthorize.clients parameter in the NetcoolOAuthProvider.xml file to the client-id values that were used when you installed the hybrid integration kit. The values can also be obtained from the /opt/IBM/JazzSM/profile/config/cells/JazzSMNode01Cell/oauth20/base.clients file. For more information, see Installing the integration kit.
  7. Apply the previous steps to all WebGUI nodes.
  8. Restart all WebGUI nodes.
  9. If you want to use a backup ObjectServer for OAuth provider updates in a high availability disaster recovery (HADR) setup, complete the following steps. Ensure that you configured an OAuth provider and an aggregation pair ObjectServer (AGG_P and AGG_B). Also ensure that you updated the AGG_GATE files for the aggregation layer ObjectServer gateway.
    1. When the OAuthProvider data source is created in each WebSphere Application Server console, go to the data source page. Click WAS Admin Console > Resources > JDBC > Data sources > OAuth provider > Custom properties.
    2. Click New and create a property that is called APPLICATIONNAME. Set the string value to WebHA. Then click Apply. Save the link that is displayed.
    3. Click New. Set the name to REQUEST_HA_SESSION and the value to true. Then click Apply. Save the link that is displayed.
    4. Click New. Set the name to SECONDARY_SERVER_HOSTPORT and the value to <Secondary_objectserver_host>:<port> to match the host and port of the DASH deployment. Then click Apply. Save the link that is displayed.
    5. Repeat steps 7a to 7d on each on-premises WAS Admin Console.
    6. Restart the WebGUI server.
    7. You can test the configuration by bringing down the primary AGG_P ObjectServer and checking that access to the Netcool Operations Insight® console is still available. You can check that updates are being made into the backup ObjectServer OauthDBSchema.OAUTH20CACHE table each time you log in to the console.
  10. Create a 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).
      • <fqdn> is the cluster FQDN.
  11. Register the OAuth client with the following command.
    <WEBGUI_PRODUCT_HOME>/waapi/bin/waapi/runwaapi -username smadmin -password <password> -file ../etc/samples/registOAuthClient.xml