Tuesday, May 16, 2023

Maximo Manage MAS HTTP End Point with OAuth Configuration

Maximo Manage supports OAuth 2.0 client credentials grant type where we send client ID and secret ID to an OAuth provider URL for authentication and receive an access token.

OAuth authenticated service API can be accessed from Maximo Manage for End Points HTTP handler and WEBSERVICE-JAX-WS handler.

Steps to create OAuth enabled End point
1. Most of OAuth using TLS or SSL handshakes, so we must upload the Manage trust store with the certificates from the OAuth provider 
2. Access to object Structure MXAPIOAUTHCLIENT should be given to the security group.


3. Configure the OAUTH client properties in the End Point applications -> "Add/Modify OAuth Clients" Action


Sample values for reference

4. Check the table MAXOAUTHCLIENT to confirm whether the token is generated correctly. 
The OAuth provider specifies an expiration interval for the access token. After expiration, a new token is generated when a new authentication request occurs. 

select accesstoken, granttype, clientid, * from maximo.maxoauthclient

5. Use the OAuth Client parameter in the HTTP Handler End point to use this authentication mechanism.


6. To test the HTTP end point with oauth, create an automation script with invokeEndPoint function to get the response. code oauthhttpendpointmas.py

from java.util import HashMap
from com.ibm.json.java import JSON
from psdi.iface.router import HTTPHandler
from com.ibm.json.java import JSONObject

metaData = HashMap()
headers = HashMap()
metaData.put(HTTPHandler.HTTP_HEADERPROPS, headers)
urlProps = HashMap()
urlProps.put("limit","5")
urlProps.put("offset","0")
metaData.put(HTTPHandler.HTTPGET_URLPROPS, urlProps)

response = service.invokeEndpoint("OAUTH",metaData,'')

obj = JSON.parse(response)
 


Reference: 

Saturday, April 15, 2023

Maximo 7.6.x HTTP end point with OAUTH 2.0 Authentication

OAuth 2.0 (Open Authorization) is standard to provide consented access and restricts actions of what a client application can perform on resources, hosted by other applications, on behalf of the user, without sharing the user's credentials.

OAuth 2.0 has different grant types to address different scenarios and they are the set of steps a client has to perform to get resource access authorization.

In this article, we will see client credentials grant type which is used for non-interactive applications e.g., automated processes, microservices, IoT etc. 

Prerequisites:

  • If the Oauth APIs are https, we need to upload the certificates in the Web Sphere server (or) whitelist the Maximo server IP by receiving End point to avoid SSL Handshake error
  • OAuth 2.0 is supported only from Maximo 7.6.1.3 and MAS. For lower versions of Maximo, we need to customize the End point to make calls to OAuth enabled resources
Maximo Components:
  • Common library script to retrieve token
  • A HTTP End point with basic configuration (URL + HTTP_METHOD)
  • A calling script to get token from library script, pass on token, URL parameter and header parameter to End point and store the response for more processing 
A common library script to retrieve token from URL is written by a script without any launch point. 
The variables defined in the statements left hand side are taken as input and those on the right side are output ones code common_lib_gettoken.py 

    

Create a End Point as HTTP Handler with basic information as URL and HTTPMETHOD.  



The calling script of any launch point passes the required parameters to library script to get the token.
This token is used as the header parameter "Authorization". The token value is concatenated with String "Bearer".

Header params and URL properties (or query parameters) are defined as HashMap. 
metaData.put(HTTPHandler.HTTP_HEADERPROPS, headers)
metaData.put(HTTPHandler.HTTPGET_URLPROPS, urlProps)  

service.invokeEndPoint("ENDPOINTNAME",metaData,"") will call the end point by adding header and query parameters code oauthhttpendpoint.py




service.error("iface",response)  will throw the output as error message in the Test script to validate the output during development phase.


Once you receive the required response, you can parse them for fields to be stored into Maximo.

Monday, March 13, 2023

Maximo Resend failed transactions via Publish channel using Automation Script

What ?
Resending failed transactions from Maximo to External System via Publish Channel using Automation Script

Why ? 
In Maintenance projects, we are requested to resend a bulk of transactions to External System on cases where outage/connection failure in the middleware.

Data Export functionality in External System --> Publish Channel tab offers the way to retrigger the records to End point. But, for the large number of records, it will take a lot of time.


How ?
We can automate it using an Object Launch Point Automation Script.


Use Maximo MeaGlobal directory to store the file and read it from the automation script:
  • SaaS Maximo 7.6.x MeaGlobal directory = ./MeaGlobalDirs
  • MAS 8.x  MeaGlobal directory =  /MeaGlobalDirs
sample whereClause file

How to run the script ?
Activate the script and launch point to execute the script


Click on the "Test Script" button


If you have enabled the Message Tracking for the publish channel in the script, you can view the outbound message sent to End point.

Please disable the Launch Point and Automation Script after resending the transactions, because it will impact the Maximo functionality on the Action application.

Note: Resending transactions to External System would cause financial mismatch or reconciliation with Maximo. Please consult with end users before resending them.

Monday, February 13, 2023

Maximo execute sql scripts without Database access

What ? 
Running DML sql scripts from Maximo UI Automation scripts without write access to database

Why ? 
Some projects won't provide write access to the database. In such cases, we need to find a way to execute update or insert sql statements for our support related tasks. 

Even if we have write access to database, there will be change freeze period between 17th December to 3rd January to block the execution of DML commands. 

How ? 
Create an automation script with Object Launch point code runsqlfile.py




If you are running the script from a cron task, the connectionKey should be retrieved from MXServer instead of implicit variable mbo.
connectionKey = MXServer.getMXServer().getSystemUserInfo().getConnectionKey()
or
connectionKey = mbo.getThisMboSet().getSystemUserInfo().getConnectionKey()

Sample Object Launch point:
Object - Asset ; 
Event Condition - 1=1 or blank



Use Maximo MeaGlobal directory to store the file and read it from the automation script.
  • SaaS Maximo 7.6.x MeaGlobal directory = ./MeaGlobalDirs
  • MAS 8.x  MeaGlobal directory =  /MeaGlobalDirs

Sample sql script runfile.sql











How to run the script ?
Activate the script and launch point to execute the script
Click on the "Test Script" button

Click on "Test" button to run the python script 



Validate the DML scripts in the database
Please disable the Launch Point and Automation Script after running the sql scripts, because it will impact the Maximo functionality on the Asset application. 

Note: Running sql scripts directly into database is not recommended by the Product team. Please do your own due diligence on executing them

Thursday, January 12, 2023

Maximo Prorate or Allocate Service Costs (Landed or Freight Cost) on POLINES in PO

What are Service Costs ? 

Service Cost includes Landed Cost, Freight Cost, Storage Cost, Managerial Personnel Cost, Advertisement Expenses, Customs Duty, Insurance Cost, Clearing Charges, Ground Maintenance, Plant Security Services etc. 

Why allocation of Service Cost is required ?

Allocation splits the standard service cost across stock tracked items on purchase order. We can allocate landed cost to PO line items even after the PO is invoiced. But, the POLINE item should not be consumed or shipped from the storeroom.

If we purchase an item in Inventory storeroom, unit cost is the cost price of the item. But there are other costs associated with purchasing items such as shipping cost etc.,  

Landed costs are a way to distribute these extraneous costs as they allow us to record the total cost of inventory per unit. It records the accurate profit reporting. 

How Services are represented in Maximo ?

Maximo enables the user to allocate or distribute the standard service cost on PO or Invoice approval.

Service Items are created in Service Items application. Services can be requested from internal or external vendors. When they are requested from Internal Vendor, we can record actual costs on Work orders without creating a PR. They are not linked to an Asset, it often include labor, tools and materials billed as single unit.

Service Item can be associated with vendors to restrict the access. 

Steps to prorate or allocate service cost on PO application

An Organization level MAXVAR variable INVOICEMGT is used to choose which application is used to prorate service cost. By default, the value is 1 where Invoice application is used for prorating. If you want to use it for PO application, set the value to 0 using below sql script.

UPDATE MAXVARS SET VARVALUE = 0 WHERE VARNAME = 'INVOICEMGT' AND ORGID = 'XXX';

Restart of server is required to reflect the changes in Maximo system

Create a PO with 3 POLINES each of quantity as 1: 
1. Item 1001 of unit cost 10
2. Item 1002 of unit cost 15
3. Standard Service Cleaning of unit cost 30 with Prorate Service ? checkbox selected



When you approve this PO, the cost of the standard service line will be distributed to all other POLINES. 
 
Calculation of prorated cost on polines
Prorate Factor = TotalProrateCostOfAllStandardServiceLines / TotalMaterialCostOfAllLines
                          =  30 / (10+15) = 1.2

TotalMaterialCostOfAllLines - i) must include only POLINES of type ITEM; 
ii) Exclude POLINES of direct issue items, services & materials and 
iii) Maxvar PRSPECIALDIRECT value should be set to 0. 

PRSPECIALDIRECT - specifies whether standard service costs are to be charged only to 'Direct Issue' line items in invoice. 

Prorate Cost  = Unit Cost * Prorate Factor
Loaded Cost = Unit Cost + Prorate Cost 

After PO Approval , the distribution of cost will be like


Item 1001 - Unit Cost= 10; Prorate Cost= 10 * 1.2 = 12; Loaded Cost= 10+12 = 22


Item 1002 - Unit Cost= 15; Prorate Cost= 15 * 1.2 = 18; Loaded Cost= 15+18 = 33


Standard Service - Unit Cost = 30 ; Prorate Cost = -30 (negative);  Loaded Cost = 0 (distributed to all item lines ) 

Friday, December 2, 2022

Data Load of Job Plan Records via Maximo Integration Framework (MIF)

MIF data loading in format of csv for Job plans require a sequence of data loads to complete a ACTIVE job plan. 

A Job Plan consists of child objects like Job Plan Tasks, Job Labor, Job Materials, Job Services and Job Tools.

Create separate Enterprise Services for Job plan, Job Plan + Job Task, Job Plan + Job Material, Job Plan + Job Labor and Job Plan + Job Service. 

A Job Plan has different statuses, and we are not allowed to modify Job Plan after it is in ACTIVE status. So, we need to follow a sequence of data load to create a single Job Plan with its related child records.

Job Plan (DRAFT status) -> Job Tasks -> Job Labor -> Job Material -> Job Service -> Job Tool -> Job Plan (ACTIVE) -> Previous Revision Job plan (REVISED)

Use External system application to load these csv files.

Job Plan 

ORGID,SITEID,JPNUM,DESCRIPTION,STATUS,TEMPLATETYPE,JPDURATION,PLUSCREVNUM,PRIORITY,INTERRUPTIBLE
EAGLENA,BEDFORD,16353456,Circuit Breaker Plan,DRAFT,MAINTENANCE,0.75,1,1,1

Job Plan + Job Task

ORGID$SITEID$JPNUM$PLUSCREVNUM$JPTASK$DESCRIPTION_id$DESCRIPTION_LD$HASLD$TASKSEQUENCE$TASKDURATION$PLUSCJPREVNUM$PREDECESSORTASKS
EAGLENA$BEDFORD$16353456$1$10$"Locomotive gear"$"a) Consign the equipment in accordance with the LOTO procedure; 
b) Consign adjacent equipment;"$$1$0

Delimiter for loading Job task data should be dollar sign ($), because we often have comma (,) in long description in the JOBTASK, so in order to differentiate the delimiter and actual content, we use $ instead of comma (,).



Job Plan + Job Labor

ORGID,SITEID,JPNUM,PLUSCREVNUM,JPTASK,CRAFT,QUANTITY,LABORHRS,VENDOR
EAGLENA,BEDFORD,16353456,1,MECH,2,1.5,

Job Plan + Job Material

ORGID,SITEID,JPNUM,PLUSCREVNUM,JPTASK,ITEMSETID,ITEMNUM,ITEMQTY,DIRECTREQ,LOCATION,STORELOCSITE
EAGLENA,BEDFORD,16353456,1,10,ITEMSETID,1120002028,1,0,LABSTORE,BEDFORD

Job Plan 

ORGID,SITEID,JPNUM,DESCRIPTION,STATUS,TEMPLATETYPE,JPDURATION,PLUSCREVNUM,PRIORITY,INTERRUPTIBLE
EAGLENA,BEDFORD,16353456,Circuit Breaker Plan,ACTIVE,MAINTENANCE,0.75,1,1,1

Maximo don't change the status of previous revision of Job plan automatically. We need to load the Job plan data to manually change the previous revision to REVISED status.

Job Plan - Previous Version

ORGID,SITEID,JPNUM,DESCRIPTION,STATUS,TEMPLATETYPE,JPDURATION,PLUSCREVNUM,PRIORITY,INTERRUPTIBLE
EAGLENA,BEDFORD,16353456,Circuit Breaker Plan,REVISED,MAINTENANCE,0.75,0,1,1

Tuesday, November 1, 2022

Configuring Websphere 7 for SAML SSO to authenticate Users in Maximo

This post details on how to configure Websphere 7.x version for SAML SSO to authenticate users in Maximo application

What is SAML ? 
  • Security Assertion Markup Language (SAML) is a standard for logging users into applications based on their sessions in another context
  • Most organizations already know the identity of users because they are logged in to their Active Directory domain or intranet, So they use this information to login into Maximo
  • SAML SSO works by transferring the user’s identity from one place (the identity provider) to another (the service provider)
  • When the user accesses the Maximo URL, the application identifies the user's origin, then redirects the user back to the Identity provider for authentication 
  • The user either has an existing active browser session with the identity provider or establishes one by logging into the identity provider 
  • The identity provider (AWS or Azure) builds the authentication response in the form of an XML-document containing the user’s username or email address, signs it using an X.509 certificate, and posts this information to the service provider
  • The service provider (Maximo) retrieves the authentication response and validates it using the certification and metadata
  • The identity of the user is established and the user is provided with Maximo access
 Steps to be followed:
1. Login to the operating system where WebSphere is installed
2. Install the default SAML ACS (Assertion Consumer Service) servlet supplied with WebSphere
  • If using Windows, open a command prompt
  • Navigate to WAS application bin directory (/opt/IBM/WebSphere/AppServer/bin on Linux/Unix or C:\Program Files\IBM\WebSphere\AppServer\bin on Windows)
  • We can install SAML ACS to a cluster or single-server. Please run the following command:    

Operating System

Command

Windows

wsadmin.bat -lang jython -f installSamlACS.py install clusterName 

(or)

wsadmin.bat -lang jython -f installSamlACS.py install nodeName serverName 

Linux/Unix

./wsadmin.sh -lang jython -f installSamlACS.py install clusterName

(or) 

./wsadmin.sh -lang jython -f installSamlACS.py install nodeName serverName

                where clusterName is the name of your WebSphere cluster ; nodeName and serverName are your node and server values respectively

  • If you are using a web server such as IBM HTTP Server in front of your application be sure that the newly installed EAR is targeted to the web server
    •  Login to the WebSphere Admin Console
    •  Using the left-hand menu go to Applications and then WebSphere enterprise  applications
    •  Click the link for WebSphereSamlSP
    •  Under Modules click Manage Modules
    • Confirm that both the cluster and the web server are assigned to the module

             If changes were required, generate and propagate the plugin configuration
    • Using the left hand side menu, go to Servers, then Server Types and click Web Servers
    • Click the checkbox next to your web server and click Generate Plug-in from the toolbar menu
    • Click the checkbox next to your web server and click Propagate Plug-in from the toolbar menu
    • Restart the web server
3. Create a new Security Domain 
  • Using the left-hand menu, select Security then Security Domains
  • Click New
  • Provide a name and description for security domain
  • Click OK
4. Confirm that Application Security is enabled
  • From the list of Security Domains, click the new domain you created 
  • Check the value next to Application Security. If the value is Enabled then you can continue on to step 5
  • Expand the Application Security section and select Customize for this domain
  • Enable the Enable application security checkbox and click Apply



5.  Configure a new Trust Association Interceptor

  • From the list of Security Domains, click the new domain you created
  • Expand the Trust Association section and select the Customize for this domain option
  • Click to enable the Enable trust association checkbox and click Apply
  • Click the Interceptors link under Trust Association
  • Click New
  • For the Interceptor class name enter com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor
  • Under Custom Properties enter the property name sso_1.sp.acsUrl with a value of your ACS URL 
  • Click New to add an additional property
  • Enter the name sso_1.sp.EntityID and provide a value for the SP entity ID and click OK


6.  Save settings and synchronize nodes

7.  Export SAML SP metadata

  • Navigate to the WAS application bin directory (/opt/IBM/WebSphere/AppServer/bin on Linux/Unix or C:\Program Files\IBM\WebSphere\AppServer\bin on Windows)
  • Launch the wsadmin tool

Operating System

Command

Windows

wsadmin.bat -lang jython

Linux/Unix

./wsadmin.sh -lang jython

  • Execute the following command 
AdminTask.exportSAMLSpMetadata('-spMetadataFileName sp_metadata.xml -ssoId 1 -securityDomainName DOMAINNAME')
    • DOMAINNAME --> should be the same name which is created on Step 3  
    • By default, metadatafile will be stored in this path "/opt/IBM/WebSphere/AppServer/profiles/ctgDmgr01"  
8. Share the Service Provider metadata to your IdP (Identity Provider like AWS or Azure Active Directory) with the following information:
  • Target URL of the application
  • IdP will provide its signing certificate inside the metadata file or request it separately and import it manually later
  • Please validate the certificate in the signature KeyInfo element of the assertion from IdP provider
9. After you received your IdP's sp_metadata.xml, ClientMaximo.cer and entityDescription file - Import them 
  • Launch the wsadmin tool using step 7
  • Execute the following commands
      • AdminTask.importSAMLIdpMetadata('-idpMetadataFileName idp_metadata.xml -signingCertAlias MyCertAlias -securityDomainName DOMAINNAME')
      • AdminConfig.save()
If the idp_metadata.xml file is not in the same path as the wsadmin tool, then you will need to specify the full path to the file.

The value for signingCertAlias can be any string; it will be used to identify the signing certificate in the WebSphere Trust Store so just choose a suitable name that is not already in the store (see Security > SSL certificate and key management > Key stores and certificates > CellDefaultTrustStore > Signer certificates for a list of keys already in the store)

DOMAINNAME - should be the same name which is created on Step 3
  • Exit the wsadmin tool and return to the WebSphere Admin Console
10. Verify TAI custom properties
  • Using the left hand menu, select Security and then Security Domains
  • Click the link to your security domain
  • Expand the Trust Association section and click the Interceptors link
  • Click com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor
 The following fields may be defined: 

Property

Value

sso_1.sp.acsUrl

value set in Step 5 - https://hostname/samlsps

sso_1.sp.EntityID

value set in Step 5 - https://hostname/

sso_1.sp.targetURL

https://hostname/maximo/webclient/login/login.jsp

sso_1.idp_1.certAlias

name of the certificate alias you provided in point 9

sso_1.idp_1.entityID

entity ID of the IdP which is provided in the IdP metadata file and will be automatically populated

sso_1.idp_1.singleSignOnUrl

URL endpoint for IdP authentication (automatically populated from metadata)

 
                  

sso_1.sp.filter – this is an optional property. We can filter out servers that can be exempted from using SSO. Usually, we enable SSO only for UI server, and filter out MIF/CRON/REPORT servers.

If you do not see the sso_1.idp_1.certAlias property then a certificate was not provided with the metadata file. We will need to obtain the certificate from the IdP and add it to WebSphere manually by going to Security > SSL certificate and key management > Key stores and certificates > CellDefaultTrustStore > Signer certificates and clicking Add.
 
Once imported, you will need to add a custom property to Trust Association Interceptor TAI   - sso_1.idp_1.certAlias and assign it the value of the new certificate alias you created

11. Finalize Security Domain setup
    • Using the left-hand menu select Security and then Security Domains
    • Expand User Realm, click the Customize for this domain radio button
    • Click Apply at the bottom of the screen and save changes
    • Go back to the Security Domain, expand User Realm (it should already be set to Customize) and click Configure... 
    • If you are not taken to the Trusted authentication realms - inbound page automatically then click the associated link in the lower right part of the screen (under Related Items)
    • Click the Add External Realm... button in the toolbar
    • Enter the value of the sso_1.idp_1.entityID from point 10 and click OK
    • Click Apply and save changes and return to the security domain configuration screen by following steps 
    • Click the Custom Properties link at the bottom of the screen
    • Add the following two properties:

Property

Value

com.ibm.websphere.security.DeferTAItoSSO

com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor

com.ibm.websphere.security.InvokeTAIbeforeSSO

com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor


    • Click OK and save changes
12. Assign security domain to servers or clusters
    • Assign server/cluster where WebSphereSamlSP.ear was deployed in point 2
    • Proceed to the security domain configuration screen as described in point 11
    • Under the heading Assigned Scopes expand the tree starting at Cell
    • Locate the server(s) or cluster(s) where you would like to enable SSO and click each one to enable it. If you are not using clusters then your servers will appear under the Nodes section. If your servers are in clusters then you must look under the Clusters section
    • Enable all appropriate servers click the OK button at the bottom of the page and save your changes

13. Restart application servers and web server to pick up configuration changes
14. Test SSO using the login URL provided by your IdP

Debugging
  • To debug issues with SAML, we need to enable trace logging on the server where the SAML ACS servlet has been installed
  • By default, WebSphere provides no feedback in the standard logs for most SSO issues 
  • If you are troubleshooting SAML in a cluster where multiple servers are running it’s recommended you stop all but one server to simplify diagnosing your problem
  • To enable trace logging for the server where the ACS servlet is installed, login to the WebSphere Admin Console and do the following
    • Using the left-hand menu select Servers then Server Types then WebSphere application servers

    • Locate the server where you installed the ACS servlet in point 2 of the Step-by-step guide and click it

    • Under Troubleshooting on the right side click Diagnostic trace service


    • Under Additional Properties click Change Log Detail Levels

    • Add the following log levels, separating each with a colon :  com.ibm.ws.security.*=all: com.ibm.wsspi.wssecurity.*=all: com.ibm.ws.wssecurity.saml.*=all:

    • Click OK and save your changes
    • Restart the server where you have enabled trace logging
    • Now test your SSO flow again and view the trace.log file in the log folder of your server for errors
    • The messages will generally give some indication of where the problem lies but you may need to find a proper person to escalate to if you cannot determine the problem