[SalesForce] Using Named Credentials to get Salesforce sessionId

I have a system that is posting data to a streaming channel which works upon data changing and a trigger firing.

The a code snippet is shown below.

        string sessionId = UserInfo.getSessionId();    
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        req.setEndpoint(uri);
        req.setMethod('POST');
        req.setHeader('Authorization', 'Bearer '+sessionId);


        string body = '{"pushEvents":[{"payload":"'+payload.escapeJava()+'", "userIds":[]}]}';


        req.setHeader('Content-Type', 'application/json');
        req.setBody(body);

        req.setCompressed(true); // otherwise we hit a limit of 32000

        try {
            res = http.send(req);                
        } catch(System.CalloutException e) {
            System.debug('Callout error: '+ e);
            System.debug(res.toString());

        } catch(System.Exception ex){
          System.debug(res.getStatusCode());
          System.debug(res.toString());
        }

I now need to call this code via scheduled apex and so now the sessionid is coming in null as its asynchronous.

What I can do is use OAuth to get an access token and use this for authentication. There is quite a lot of setup to this and storing usernames/passwords/securitytokens (and managing them) is something that doesn't appeal!

I have come across the Named Credentials functionality and wonder if this is something I can leverage? Anybody tried this?

I have tried

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Salesforce');
req.setMethod('POST');

Http http = new Http();
HTTPResponse res = http.send(req);


System.debug(res.getBody());

where Salesforce is the Named Credential with the following details:-

The result from Developer Console is

12:05:11.560 (560650534)|CALLOUT_RESPONSE|[6]|System.HttpResponse[Status=Bad Request, StatusCode=400]
12:05:11.560 (560668002)|HEAP_ALLOCATE|[6]|Bytes:96
12:05:11.560 (560819528)|VARIABLE_ASSIGNMENT|[6]|res|"System.HttpResponse[Status=Bad Request, StatusCode=400]"|0x319e2ef7
12:05:11.561 (561088589)|USER_DEBUG|[9]|DEBUG|{"error":"unsupported_grant_type","error_description":"grant type not supported"}

Any help appreciated.

Best Answer

You can do this, but you'll need to do a bit more work to use it.

  • First, Create a connected app with oAuth, select refresh_token (at a min) for the oAuth scope
  • Second, Create an auth provider of the salesforce type. Give it the oauth consumer key and consumer secret that you got when you created the connected app.
  • Finally, create a Named Credential using oauth, and your auth provider. When you save the named credential, it will prompt you to log in to a SF org.

Once you've logged in there, the refresh token is saved and used by the named credential. From there, you can make callouts to access data. Note whatever user you login as there is the user your api calls will run as.

Related Topic