Connector Rule for Web Service to Generate Random String and Send to API URL

Hello,

I have a requirement for the following:

  • We need to connect to a web service application using the web service connector. This web application requires a new random generated string (csrf token) to be included in the API URL for every call. For example, the call to do a Test Connection is “/api/v1/users?csrftoken=ABCD123”. The value of the “csrftoken” needs to be unique for every call.

So, the approach I’m thinking to do this will be to leverage on the Connector Rule for Web Service specifically using “Web Services Before Operation Rule” to perform the following:

  1. Define string variable.
  2. Use random generated number and store to string variable.
  3. Include this generated string variable as part of the value for “csrftoken” in the API URL.

My question would be, since I’m not very familiar with Beanshell code, would like to ask:

  1. Is the above approach viable?
  2. Is there another better/simpler approach?
  3. Any sample Beanshell script for the above requirement?

Thank you so much!
Regards,
MingZheng

Hi @MingZheng,

Can you let me know this random generated value is used for every API call or not.

if this random string required for every operation follow below steps:
1.Create a string
2.Generate a random string value.
3.Concat generated string value with API URL. using below code lines:

String csrftoken = "";
String contextUrl = "/api/v1/users?csrftoken="+csrftoken;

//add below statements in last line your code 
requestEndPoint.setContextUrl(contextUrl);
return requestEndPoint;

Thank You.

Hi @gogubapu ,

Thank you much for your guidance. Yup, it will be random generated and used for every API call.

Thanks for the code lines too. I have also just tested using variable and it can set accordingly. Now my follow up questions will be:

  1. What will be the code/method to generate a random string and store to a variable?

Thank you!

Use below code to achieve:

import sailpoint.connector.webservices.WebServicesClient; 
import sailpoint.connector.webservices.EndPoint; 
import sailpoint.connector.ConnectorException;
import sailpoint.tools.GeneralException; 
import sailpoint.tools.Util;
import connector.common.Util; 
import java.lang.Exception; 
import java.security.SecureRandom;

	private String generateAlphanumericNonce(int length) {
		String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
		SecureRandom secureRandom = new SecureRandom();
        StringBuilder nonce = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            nonce.append(CHARACTERS.charAt(secureRandom.nextInt(CHARACTERS.length())));
        }
        return nonce.toString();
    }
	try
	{ 	
                // Getting the BaseURL.
		String BaseUrl=(String) application.getStringAttributeValue("genericWebServiceBaseUrl");
		String csrftoken = generateAlphanumericNonce(7); // Generate a nonce of length 7			 
		String updateUrl = BaseUrl+"/api/v1/users?csrftoken="+csrftoken;
		log.info("================================== updateUrl =========================== =" +updateUrl);
		requestEndPoint.setFullUrl(updateUrl);
		log.info("----------------------- Exiting BeforeOperation_Rule---END----------------");
	} 
	// Catch block for handling the exceptions.
	catch(Exception ex) 
	{ 
		log.error("-----Exception Occured while execting the rule-----"+ex); 
    } 
	return requestEndPoint;
3 Likes

Thanks~ lemme test it

1 Like

Hi @MingZheng,

I had a similar kind of requirement and i ended up using the EPOCH time as it will be always incrementing here’s a code snippet to get the time.
P.S if your API endpoint needs anything random and there is no need of alphanumeric string then you can use this to get a guranteed random string.

import java.time.Instant;
long exp = Instant.now().getEpochSecond();
String val = String.valueOf(exp); //convert to String

You can use this snippet to get the unique value always as it is based on time that is in seconds.

Hope this can help.

1 Like

Hi Neeraj,

thank you so much for your guide~ that is a great advice on using EPOCH time~
For my case, since the limit is min and max of 12 characters, I’ve used the code guided by bapu. it works very well. i just need to include the definition for baseUrl.

Thank you all! Really appreciate it~

2 Likes

Hi all,

I had applied the above beforeOperation rule to an “Account Aggregation” operation type. When calling this endpoint, this will return me with an array value of 2 items. However, when beforeOperation rule is applied, I am only getting back the first value of the array. I further tested by removing the beforeOperation rule, then I am able to get 2 values from the array.

Any idea what is causing this behaviour?

Its okay now. Mistake on the limit parameter.
Thanks!

Thank you!

Following on from this excellent idea, you can put this into the Create/Update profiles and reference it the Body:

{
    "name": "",
    "description": null,
    "usageType": "CREATE",
    "fields": [
        {
            "name": "correlationId",
            "transform": {
                "type": "dateFormat",
                "attributes": {
                    "input": {
                        "type": "dateMath",
                        "attributes": {
                            "expression": "now",
                            "roundUp": true
                        }
                    },
                    "inputFormat": "ISO8601",
                    "outputFormat": "EPOCH_TIME_JAVA"
                }
            },
            "attributes": {},
            "isRequired": false,
            "type": "",
            "isMultiValued": false
        },

So no need to write a BeforeProvisioning Rule

EDIT: Changed the input to ISO8601, gives a better ouput

2nd EDIT: Since writing this, the input format now fails, and only accepts this “inputFormat”: “yyyy-MM-dd’T’HH:mm”, which means when doing many API calls quickly, they will all have the same number due to the lack of ‘seconds’, so might need to stick a random number on the end of it to make it unique.

1 Like

Nice! Thank you for the advice! These would definitely be more helpful as no need for rule process! Thank you Phil!

1 Like