Authentication for REST and SOAP invocation

The cloud portal supports the use of basic authentication in invoking REST and SOAP APIs. Instead of hardcoding login credentials into your application, pull them in from a separate file.

The recommended practice for using login credentials is to keep them in a separate file, and to call them from your application during authentication. With this approach, you do not have to alter the code of your application every time you change your credentials. The primary alternative is to add the credentials directly to your application. This approach risks the introduction of mistakes to your code, and requires you to redeploy the application every time you update the credentials.

The cloud portal offers two types of credentials:

  • Service credentials: These credentials are exempt from the password renewal polices of the cloud portal. They are only valid for calling REST and SOAP APIs. Users cannot use them to log in to the portal or its components (see Service credentials for client application).
    Note: Operational Decision Manager on Cloud supports SOAP 1.1. It does not support later versions of SOAP.
  • Local accounts: These user accounts have credentials that are subject to the password renewal policies of the cloud portal. Users and applications can use these credentials to log in to the portal and its components.
Tip:

Use service credentials for authenticating your applications. They provide better security, and you can apply your own policies for updating login credentials.

SAML users

You cannot use SAML login credentials to authenticate a decision service. If you use SAML to log in to the cloud portal, you must request service credentials for REST or SOAP invocation (see Getting a set of service credentials). IBM® internal users automatically use SAML to log in to the portal, and must request service credentials.

Calling service credentials

The following steps show you how to set up your application to call service credentials from a separate file. Depending on your IT strategy, you can use the credentials of a local account in place of the service credentials.

  1. Obtain your service credentials from your cloud administrator. Only a cloud administrator can generate service credentials. The service credentials include a functional ID and a password.
  2. Place the service credentials in a property file, for example, sc.properties:
    odmoc.url=https://mytenant.bpm.ibmcloud.com/odm/dev
    odmoc.functionalId=api1.fid@t1023
    odmoc.password=xfmptNJsQONCvRXB1bYS1AxlIcYyh1UR2y/LMpyx

    The properties in this example are defined as follows:

    Property Description
    odmoc.url The URL of your tenant of the cloud portal
    odmoc.functionalId The functional ID in the service credentials
    odmoc.password The password in the service credentials
  3. In your application, add the code that calls the service credentials from the file sc.properties. The following code is from a Java™ client:
    package test;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.util.Properties;
    
    import org.apache.commons.codec.binary.Base64;
    import org.apache.http.HttpResponse;
    import org.apache.http.Header;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.ssl.SSLContextBuilder;
    import org.apache.http.util.EntityUtils;
    
    import com.ibm.json.java.JSONObject;
    
    public class OdmRestClient {
        
        public static void main(String[] args) throws Exception {
    	// The builder should be configured to connect using HTTPS to ODM on Cloud,
    	// and must use a secure cipher with hostname verification. The following
    	// code does not reflect all the required settings.
            HttpClientBuilder builder = HttpClients.custom();
            builder.disableRedirectHandling();
            HttpClient client = builder.build();
    
            // This code calls the service credentials from the file sc.properties. 
            //It reads the url, functional Id and password from a property file.
            String configFile = "sc.properties";
            FileInputStream fistream = null;
            try {
                fistream = new FileInputStream(configFile);
            }
            catch (FileNotFoundException e) {
                System.out.println("Could not open file: " + configFile);
                System.exit(0);
            }
            Properties props = new Properties();
            props.load(fistream);
    
    	String baseurl = props.getProperty("odmoc.url");
            String fid = props.getProperty("odmoc.functionalId");
            String pwd = props.getProperty("odmoc.password");
    	String url = baseurl + "/res/api/v1/ruleapps?count=true";
    	
            // Basic Authentication header value
            String baHeader = fid + ":" + pwd;
    	System.out.println("BA header is: " + baHeader);
            baHeader = Base64.encodeBase64String(baHeader.getBytes());
            
            // execute request
            HttpResponse response = null;
    	System.out.println("** Calling: " + url);
    
            HttpGet request = new HttpGet(url);
            request.setHeader("Authorization", "Basic " + baHeader);                        
            try {
               response = client.execute(request);
            }
            catch (Exception e) {
               throw new Exception("Could not execute API call, reason: " + e.getMessage());
            }
            
            int httpRespCode = response.getStatusLine().getStatusCode();
    	System.out.println("Response code is: " + httpRespCode);
    
            if (httpRespCode==302) {
                // We are in one of these 3 cases: wrong ID, wrong password, account locked
                System.out.println("Basic auth access denied.");
    	    System.out.println("Reason1: Wrong ID or password");
    	    System.out.println("Reason2: Account locked after some unsuccessful attempts");
            }                        
            else if (httpRespCode==401) {
    	    // Aithorization is not granted to access the URL
                System.out.println("ODM API access was denied: you are not authorized");
            }
            else if (httpRespCode==200){                    
    	    // Correct execution result, extract the HTTP response
                String json = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println("Successful invocation, result : " + json);
            }
    	else {
    	    // Diagnose why such a code. Contact IBM support with all the details.
    	    System.out.println("Unexpected return code: " + httpRespCode);
    	}
        }
    }

The HTTP client side can return the following codes during authentication:

Code Description
Code 200 This code denotes a correct execution result. The return result is the actual response to the API call. You can get Code 200 in the case of wrong credentials when the redirect handling is not deactivated. To diagnose a connection problem accurately, deactivate the redirect handling.
Code 302 The HTTP request returns Code 302 when the functional ID or password is wrong, or the account is locked. The code does not provide the cause of the authentication failure. If the account is locked, you can try waiting one hour for the account to be unlocked automatically. If the account is not unlocked automatically, contact your cloud administrator. This code is returned when the redirect handling is deactivated
Code 401 You get this code when the credentials are correct, but they are not authorized to access the URL. You must ask your cloud administrator to grant the required authorization. (Note: This code is not currently returned but authorization could be enhanced in the future.)
Other codes If you get any other code, contact IBM for assistance (see Troubleshooting and support).