2

I am trying to use the Named credentials for the first time without using the named credentials directly if I call the endpoints with credentials it works perfectly fine which uses OAuth where I get the Bearer/Access token from Microsoft and use them to post the data to the external system like below

@future (callout=true)
public static void createSegmentD365(String subSegmentID) {
    String clientId = 'xxxxxxxxxxx';
    String clientSecret = 'xxxxxxxxxx';
    String tenant_id = 'xxxxxxxxxx';
    String resource = 'https://dev.cloudax.dynamics.com';

    String reqbody = 'grant_type=client_credentials&client_id='+clientId+'&client_secret='+clientSecret+'&tenant_id='+tenant_id+'&resource='+resource;

    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setBody(reqbody);
    req.setMethod('POST');
    req.setEndpoint('https://login.microsoftonline.com/abc.org/oauth2/token');
    HttpResponse res = h.send(req);

    deserializeResponse resp1 = (deserializeResponse)JSON.deserialize(res.getbody(),deserializeResponse.class);
    String bearerToken = resp1.access_token;     

    JSON2Apex js = new JSON2Apex();
    js.dataAreaId = 'jax';
    js.SegmentCode = subSegmentID;

    String jsonBody = json.serialize(js);    

    Http http1 = new Http();
    HttpRequest req1 = new HttpRequest();


    req1.setEndpoint('https://dev.cloudax.dynamics.com/data/parentAccounts');
    req1.setMethod('POST');
    req1.setTimeout(20000);
    req1.setHeader('Authorization','Bearer '+bearerToken);
    req1.setBody(jsonBody);
    req1.setHeader('Content-Type', 'application/json;charset=UTF-8');
    HttpResponse res1 = http1.send(req1);
   }

I am trying to use the named credentials now. I set the AUTH Provider and Named Credentials and I get the Authenticated status in the Named Credentials like below

enter image description here

So I changed the Apex Callout like

   @future (callout=true)
   public static void createSegmentD365(String subSegmentID) {
    HttpRequest req = new HttpRequest();
    req.setEndpoint('callout:D365Credential/data/parentAccounts');
    req.setHeader('Authorization','Bearer {!$D365Credential.access_token}');
    req.setHeader('Content-Type', 'application/json;charset=UTF-8');
    req.setMethod('POST');
    req.setTimeout(20000);
    req.setBody(jsonBody);
    Http http = new Http();
    HTTPResponse res = http.send(req);
    System.debug('Response Body=========' + res.getBody());      

In the debug I get the Authentication failed, not sure what I am missing here any help is greatly appreciated

enter image description here

6
  • You didn't provide request/response from Postman, tough to know what you did there. Based on your Apex snippet, the String reqbody = ... line of code is not equivalent to your auth provider configuration.
    – identigral
    May 27, 2020 at 21:15
  • @identigral Added the screenshot of the Postman. I am able to successfully call the endpoints without using named credentials with my above apex callout
    – user81642
    May 27, 2020 at 21:33
  • When you acquire the token from login.microsoftonline.com, you have all these parameters in your Postman and Apex snippet. Where are they in the Named Credential?
    – identigral
    May 27, 2020 at 21:41
  • How do we give them, I tried to add to the Authorization endpoint URL like ?grant_type=client_credentials&tenant_id=xxxxxxx&resource=dev.cloudax.dynamics.com which doesnt let the Authentication to be successful looks like it will use my username/password to authenticate instead of the Client id/client secret. I dont have access to the application
    – user81642
    May 27, 2020 at 21:45
  • OpenId Connect auth. provider does not support grant_type=client_credentials. This is undocumented..but similar questions have been answered on this forum that explain that. That aside, some parameters can be appended and this is documented. Whether appending some of these parameters will or will not be useful depends on the target service (Microsoft in this case). Sounds like you're better off with Apex..
    – identigral
    May 27, 2020 at 21:54

1 Answer 1

5

This line is not needed when using named credentials as callout endpoints:

req.setHeader('Authorization','Bearer {!$D365Credential.access_token}');

From the example

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:My_Named_Credential/some_path');
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());

Note

I was able to find this question which shows that form assembly has some funky requirements. If you absolutely need to include this header for some reason, I think you're using the wrong merge field. This documentation shows that it should OAuthToken instead of access_token.

req.setHeader('Authorization','Bearer {!$D365Credential.OAuthToken}');
10
  • I did both recommendation tried to remove the setHeader also changed from the access_token to OAuthToken both the ways I am getting error NAMED_CREDENTIAL_REQUEST NamedCallout[Name=D365Credential, Endpoint=https://dev.cloudax.dynamics.com/data/parentAccounts, Method=POST, External Credential Type=EXTERNAL, HTTP Header Authorization=Method: Bearer - Authorization Credential Hash: -635680243, Retry on 401=True]
    – user81642
    May 27, 2020 at 16:04
  • Is there any way to debug the OAuthToken generated I tried System.debug('{!$D365Credential.OAuthToken}'); doesnt work it treats it as a String
    – user81642
    May 27, 2020 at 16:21
  • The merge fields will only work when part of http requests, otherwise as you see it will use it as a string. Our org uses a host of named credentials and we have never had an issue, if the above does not work for you, contact the vendor you are trying to connect to and ask for assistance. They may require additional information that is not provided out of the box as in the above case with FormAssembly.
    – gNerb
    May 27, 2020 at 17:27
  • Thank you, point is we are able to connect to the vendor directly without the Named Credentials passing in the Req body and Authorization header as I shown above
    – user81642
    May 27, 2020 at 17:30
  • Seems like the merge field should be AuthorizationHeaderValue?
    – Adrian Larson
    May 27, 2020 at 22:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .