1

Im facing issues trying to generate the auth header in Apex when using Named Credentials.

Unfortunately I cannot use the standard Named Credential approach (auto header generation) as I have to embed a session id in the header.

Named Credential setup

Blob authHeaderValue = Blob.valueOf('{!$Credential.Username}' + ':' + sessionId);
HttpRequest request = new HttpRequest();
request.setMethod('POST');
request.setEndpoint('callout:endpointexample');
request.setHeader('Content-Type', 'application/json');
request.setHeader('Authorization', 'Basic' + ' ' +  EncodingUtil.base64Encode(authHeaderValue));
Http http = new Http();
HTTPResponse res = http.send(request);

If I hardcode the username it works fine so assuming {!$Credential.Username} is the issue here.

4
  • 1
    Hi, welcome to SFSE. Are you receiving any error message from the external service? If so, how does it look like? May 26 at 10:48
  • Hi thanks. Just a 400 bad request error which isn't very useful.
    – Pete
    May 26 at 13:22
  • 1
    What about testing it via curl, Postman or any other HTTP request tool? Does it work fine there? May 26 at 14:45
  • the authentication in the named cred is set to Password Auth.
    – Pete
    May 26 at 17:13

2 Answers 2

2

Named Credential acts as a runtime proxy. The proxy receives your HTTP request then searches its body or headers for the merge field as a literal string. If NC doesn't find the field, it won't interpolate (merge) it:

This works: request.setHeader('X-Username', '{!$Credential.Username}');

This also works (assuming Generate Authorization Header is unchecked): request.setHeader('Authorization', 'Bearer: {!$Credential.Username}');

This does not work:

Blob authHeaderValue = Blob.valueOf('{!$Credential.Username}' + ':' + sessionId);
request.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(authHeaderValue));

...nor does this:

Blob authHeaderValue = Blob.valueOf('{!$Credential.Username}');
request.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(authHeaderValue));

...nor this:

Blob authHeaderValue = 
request.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf('{!$Credential.Username}')));
1

I don't think you can use a merge field like this, because it's replaced when the call is made.

Effectively you're ending up with the encoded value of the literal text {!$Credential.Username}:*sessionid*.

It would be worth putting in a bit of logging to check this.

1
  • Upvoted your answer since it is essentially correct. One caveat: you didn't explain what when the call is made means and that's a critical element.
    – identigral
    May 26 at 22:00

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.