Get dynamic token with a web services connector

Hello Developers

I am configuring a web services connector to consume the methods of an API. I am having problems because for some methods it is necessary to first generate a token that changes from time to time.

I configured the connector with a custom authentication in the connection settings section and in the HTTP operations I put a Custom Authentication at the beginning where I indicate the URL where the token will be obtained. I pass as a header an Authorization with the value user:password encrypted in base64 that is saved in the variable $application.refresh_token$. However, when I perform an account aggregation it returns zero (0) accounts.

Running an aggregation but with a basic authorization only with user and password and placing the dynamic token (obtained through postman) in the header of the methods that need it, it does return accounts.

I would like to know if there is an alternative to leave the authentication type as Basic and obtain the token in some other way since with custom authentication it is not working.

I would appreciate any help.
Regards.

It’s always good to share the config to see what is ‘missing’ from that point of view. Make sure to not share any credentials or specific URLs though.

If the account aggregation returns 0 results, but succeeds it can also mean that the mapping is not performed properly?

Have you tried the same in postman?

Hi @sauvee thanks for your response

The configuration of my conector is the next:

In the Connection Settings I set the next information:
Authentication Type: Custom Authentication
Base URL: https://mydomain.com:443
Username: MyUsername
Password: MyPassword
Refresh Token: MyUsername:MyPassword (base64 encoded)

In HTTP Operations in this order:

  1. Operation Type: Custom Authentication
    Custom Authentication URL: https://mydomain.com:443/csrf_token
    HTTP Methos: POST

Headers:
Authorization: Basic $application.refresh_token$
Content-Type: application/json

Body:
raw : {“requested_lifetime”: 300}

Response Information:
Root Path: $

Response Mapping:
Schema attribute: accesstoken
Attribute Path: csrf_token

  1. Operation Type: Account Aggregation
    Context URL: https://mydomain.com:443/users
    HTTP Methos: GET

Headers:
CSRF-TOKEN: $application.accesstoken$
Content-Type: application/json

Response Information:
Root Path: $.users

Response Mapping:
Schema attribute: user_id, given_name, family_name, email
Attribute path: user_id, given_name, family_name, email

In the postman, first I get the token in the endpoint https://mydomain.com:443/csrf_token with basic authentication (username and password). Then I set the token in the header key CSRF-TOKEN and with the same basic authentication and the response is something like that:

{
    "users": [
        {
            "user_id": "[email protected]",
            "email": "[email protected]",
            "given_name": "user1",
            "family_name": "test"
        },
        {
            "user_id": "[email protected]",
            "email": "[email protected]",
            "given_name": "user2",
            "family_name": "test2"
        }
    ]
}

I hope this can help.

Regards.

@jacob_islas you can use a before operation rule to fetch the token and patch that rule on each and every operation

Hello @schattopadhy and thanks for your reply

It would be a connector rule of before provisioning, right?
Do you have an example of the structure that makes up that rule, I don’t understand how to start.

@jacob_islas you can refer the below.Please help to mark it as solution if it helps

tyimport sailpoint.connector.webservices.WebServicesClient; 
import sailpoint.connector.webservices.EndPoint; 
import sailpoint.connector.ConnectorException; 
import sailpoint.object.Application; 
import sailpoint.tools.GeneralException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.HashMap; 
import java.util.Map; 
import sailpoint.tools.Util; 
import java.io.IOException; 
import java.util.Iterator; 
import connector.common.Util; 
import java.lang.Exception; 
import connector.common.JsonUtil; 
import connector.common.JsonUtil.JsonParser; 
 
log.info(\"-----------------------Entering _BeforeOperation_Rule---Start----------------\"); 
log.info(\"-------------Global Variable Declaration----------------------------\"); 
log.info(\"------Declaring base URL--------------------------------------------\"); 
String baseUrl=\"\"; 
log.info(\"-------------------Declaring Client id------------------------------\"); 
String client_id = (String) application.getStringAttributeValue(\"client_id\"); 
log.info(\"-------------------Declaring Client secret------------------------------\"); 
String client_secret = (String) application.getAttributeValue(\"client_secret\"); 
log.info(\"-------------------Declaring URL for the Authorization------------------------------\"); 
String authenticationURL = baseUrl+ \"/security/auth-external\"; 
log.info(\"-------------------Header Mapping(Content Type)------------------------------\"); 
Map headers = requestEndPoint.getHeader(); 
 
try{ 
	log.info(\"----------Performing Null Check----------------------\"); 
	if (Util.isNotNullOrEmpty(authenticationURL) && Util.isNotNullOrEmpty(client_id) && Util.isNotNullOrEmpty(client_secret)) { 
	log.info(\"-------------------Adding Response Status-----------------------------\");	 
	// adding expected response status from the target system 
	List allowedStatuses = new ArrayList(); 
	allowedStatuses.add(\"2**\"); 
	Object json =  \"{\\\"client_id\\\":\\\"\"+client_id+\"\\\",\\\"client_secret\\\":\\\"\"+client_secret+\"\\\",\\\"audience\\\":\\\"\"+baseUrl+\"\\\",\\\"grant_type\\\":\\\"client_credentials\\\"}\"; 
	String responseData = restClient.executePost(authenticationURL, json, headers, allowedStatuses); 
	log.info(\"------------------------Execution Complete------------------------------------\"); 
	log.info(\"-------------------Genarating Authorization Token-----------------------------\"); 
		if (Util.isNotNullOrEmpty(responseData)) { 
			Map responseMap = JsonUtil.toMap(responseData); 
			String accessToken = responseMap.get(\"access_token\"); 
			String bearerToken = \"Bearer \"+accessToken; 
			headers.put(\"Authorization\",bearerToken); 
			requestEndPoint.setHeader(headers); 
			log.info(\"-------------------Authorization Token Generation Successful-----------------------------\"); 
		} 
		else { 
			log.error(\"unable to set the header, response data null or empty\"); 
		} 
	} 
	else { 
		log.error(\"unable to set the header as url, id or secret null or empty\"); 
	} 
	log.error(\"-------------------Exiting _BeforeOperation_Rule---End--------------------------------------------\"); 
}catch(Exception e){ 
		log.error(\"-----Exception Occured while execting the rule-----\"); 
} 
return requestEndPoint;",
            

You can solve this in the way you did, without a rule.

In your response mapping, use a new attribute that doesn’t exist yet, and ensure the attribute is encrypted.

Please follow the following guide thoroughly:

Right now you are mapping to ‘accesstoken’ which does already exist in the application, so this will not work. Use something like ‘custom_accesstoken’ and it should work.