[SalesForce] REST HTTP Response Error : {“error”:”invalid_client”,”error_description”:”invalid client credentials”}

I am trying to achieve a REST based integration between two Salesforce instances (both of them developer editions)

Expense created from source instance will be sent to the destination instance via POST.

This is my integration class in the source instance.

public class IntegrateExpenses
{

//To deserialize the response...
public class OAuth2
{

   public String Id {get;set;}
   public String issued_at{get;set;}
   public String instance_url{get;set;}
   public String signature{get;set;}
   public String access_token{get;set;}

}


@future(callout=true)
public static void sendexpense(String ExpenseName,String Type,Integer Amount)
{

String clientId = '3MVG9ZL0ppGP5UrDhLqebweqGDkIkyGQRjYkfWtLLSwKDal0AhSWZIG7EU7gsYQn4JjfCt.SOoBrJLmyEpslT';
String clientSecret = '7217724494220744623';
String username = 'apiuser1982@gmail.com';
String password = 'qazwsx123UKBZb1SEA3LgCcptvGBb8ibpk';
String reqbody = 'grant_type=password&client_id='+clientId+'&clientSecret='+clientSecret+'&username='+username+'&password='+password;

HTTP h = new HTTP();
HTTPRequest req = new HTTPRequest();
req.setBody(reqbody);
req.setMethod('POST');
req.setEndPoint('https://login.salesforce.com/services/oauth2/token');
HTTPResponse res = h.send(req);

System.debug('~~~ 1 Response Body '+res.getBody());
System.debug('~~~ 1 Response Status '+res.getStatus());
System.debug('~~~ 1 Response Status Code '+res.getStatusCode());

OAuth2 objAuthenticationInfo = (OAuth2)JSON.deserialize(res.getBody(),OAuth2.class);
//RequestWrapper rest = new RequestWrapper();

if(objAuthenticationInfo.access_token != null)
{



    JSONGenerator gen = JSON.creategenerator(true);
    //gen.writestartarray();
    gen.writestartobject();
    gen.writestringfield('ExpenseName',ExpenseName);
    gen.writestringfield('Type',Type);
    gen.writenumberfield('Amount',Amount);
    gen.writeendobject();
    //gen.writeendarray();

    System.debug('~~~~ JSON Object '+gen.getAsString());

    String jsonstr = gen.getAsString();

    HTTP h1 = new HTTP();
    HTTPRequest req1 = new HTTPRequest();
    req1.setHeader('Authorization','Bearer'+objAuthenticationInfo.access_token);
    req1.setHeader('Content-type','application/json');
    req1.setHeader('accept','application/json');

    req1.setBody(jsonstr);
    req1.setMethod('POST');
    req1.setEndPoint('https://login.salesforce.com/services/apexrest/Expense');

    HTTPResponse res1 = h1.send(req1);

    System.debug('~~~ 2 Response Body '+res.getBody());
    System.debug('~~~ 2 Response Status '+res.getStatus());
    System.debug('~~~ 2 Response Status Code '+res.getStatusCode());



}






}


}

I am calling the above integration class via after insert trigger (in the source instance) as below

enter image description here

This is the screenshots from destination instance of the connected app
enter image description here

enter image description here

This is my debug log (from the source instance)

20:22:36.038 (38490065)|CALLOUT_REQUEST|[32]|System.HttpRequest[Endpoint=https://login.salesforce.com/services/oauth2/token, Method=POST]
20:22:36.215 (215459286)|CALLOUT_RESPONSE|[32]|System.HttpResponse[Status=Bad Request, StatusCode=400]
20:22:36.215 (215509729)|SYSTEM_METHOD_EXIT|[32]|System.Http.send(ANY)
20:22:36.215 (215567868)|SYSTEM_METHOD_ENTRY|[34]|System.HttpResponse.getBody()
20:22:36.215 (215636068)|SYSTEM_METHOD_EXIT|[34]|System.HttpResponse.getBody()
20:22:36.215 (215793285)|SYSTEM_METHOD_ENTRY|[34]|System.debug(ANY)
20:22:36.215 (215806284)|USER_DEBUG|[34]|DEBUG|~~~ 1 Response Body {"error":"invalid_client","error_description":"invalid client credentials"}

Q:

From my analysis, it looks that client id (consumer key) is incorrect. But as can be seen from the code and screenshots I don't see any mismatch.

Can someone let me know as to what could be the reason behind me getting this "invalid client credentials" error message in HTTP response ?

UPDATE :

Another thing that I noticed that is do not see login attempt being done at this API user's login history.

Best Answer

For others having the same issue you could be missing the security token:

For access via the API or client app, if the Multi-Factor Authentication on API Logins permission is set on the user profile, users enter a TOTP verification code generated by an authenticator app. If the permission isn’t set, users must add their security token to the end of their password to log in. A security token is a generated key from Salesforce. For example, if a user’s password is mypassword and the security token is XXXXXXXXXX, the user enters mypasswordXXXXXXXXXX to log in. Some client apps have a separate field for the security token.

Users can get their security token by changing their password or resetting their security token via the Salesforce user interface. When a user changes a password or resets a security token, Salesforce sends a new security token to the email address on the user’s Salesforce record. The security token is valid until the user resets the security token, changes a password, or has a password reset.

Reference: https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_concepts_security.htm

Related Topic