2

I've configured a Named Credential to use the JWT authentication protocol (not JWT Token Exchange), but when the component makes a call to my service using the named credential, I don't get the JWT as an Authorization header. I checked all the headers, and don't see an "Authorization" header at all.

When I change the authentication type to basic or JWT Token Exchange, then it works, sending the values I expect.

Should there be a JWT in the Authorization header?

Do I have my issuer and audience set up correctly? When I experimented with JWT token exchange, it seemed picky about those.

Certificate: (empty)

Identity Type: Named Principal

Authentication Protocol: JWT

Issuer: <the host name of my Salesforce instance>.lightning.force.com

Named Principal Subject: <my user name>

Audiences: https://<the base URL of the remote server>

Token Valid for: 10 Seconds

JWT Signing Certificate: My_Sample

Generate Authorization Header: checked

Allow Merge Fields in HTTP Header: checked

Allow Merge Fields in HTTP Body: checked

Outbound Network Connection: blank

My Apex code (actually written by someone else a long time ago), which works for Basic Authentication

      HttpRequest request = new HttpRequest();
      String statusApi = 'callout:my_named_connection/api/status';

      request.setEndpoint(ApiProxy.appendUrlParams(statusApi, request));
      request.setMethod('POST');
      request.setHeader('Content-Type', 'application/json');
      request.setHeader('Content-Length', String.valueof(body.length()));
      request.setBody(body);  

      request.setTimeout(10000);
      HttpResponse  response = http.send(request);
3
  • 1
    The Certificate field is for callout endpoint, you want to leave that blank. Did you check Generate Authorization Header ? Please edit your question and include the Apex snippet that uses your NC.
    – identigral
    Dec 21, 2021 at 21:50
  • Done. It uses Basic Authentication now; I'm thinking that I should be able to just switch the named credential to JWT without making a code change. Is that right?
    – sea-rob
    Dec 21, 2021 at 23:02
  • Edited to clarify I'm not getting an Authorization header at all.
    – sea-rob
    Jan 10 at 16:16

1 Answer 1

2
+50

You don't get a "JWT" header, because JWT typically (and in the case of Salesforce) uses the "Authorization" header with the Bearer scheme. The Authorization header contains all the JWT information needed. There is no "JWT" in the "Authorization" header itself, because a) it's Base64 encoded and b) does not state "JWT" as such in its three constituents.

Take the HTTP request generated by Salesforce, copy the long string after "Bearer" and get it decrypted and split up into its parts for example here:

https://jwt.io/

Explanations of the elements can be found in the relevant RFCs 7515 and 7519.

Decoding the bearer and finding its elements in the spec helps answering the other questions.

E.g. you will have noticed that Salesforce's "Issuer" becomes "iss" in the (decoded) Bearer token; one RFC uses "joe" as an example for a possible value, but it can be any "StringOrURI". You could provide an URI (which should be "https://...my.salesforce.com", not "... lightning..."), but I'd suggest a Salesforce user name. This is "OPTIONAL"; I don't know your endpoint provider, but if you are not told explicitly otherwise, the success of the communication should not depend on it.

Salesforce's "Audience" is "who or what the token is intended for". (The Bearer token has "aud" and this is only described by RFC 7519.) Although also optional, it is more often decisive. It is also "StringOrURI". https://<the base URL of the remote server> looks alright to me.

Finally, the decoded Bearer token has typ: "JWT" - the closest you can get to what you were looking for.

I'd uncheck the two check boxes for "Merge Fields". At least the code you provided doesn't show any use of merge fields.

4
  • Thank you! I will try unchecking the "merge fields" and see if that helps. To be clear, I'm not getting an "Authorization" header at all.
    – sea-rob
    Jan 10 at 16:11
  • I can not imagine any reason why you shouldn't get an "Authorization" header, when "Generate Authorization Header" is checked. I've played with this yesterday while writing this up and did get the Authorization header nicely. Un-checking "Allow Merge" is unlikelyto make a difference. How do you verify the headers? Suggestion: Configure "httpbin.org/headers" as your endpoint of a test Named Credential (and as a Remote Site in SF's Setup), change the HTTP method in Apex to GET and System-debug the response body. Jan 10 at 16:56
  • Thank you! Does Salesforce not support an Authorization header, or "JWT Token", for POST? I can test with GET, but in the end we do POST data to our server.
    – sea-rob
    Jan 10 at 17:16
  • Salesforce creates Authorization headers for POST as well, no problem with that. The following endpoint returns your POST request: httpbin.org/anything . Jan 10 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.