jwtsalesforce

Username/password JWT with Salesforce Named Credentials


I need to integrate with a service that uses an authentication flow I'm not familiar with and wondering can I use Named Credentials with it?

The flow requires that I first get a JWT token by passing a username & password in a JSON body. Then I can use that as a regular bearer token.

  1. Get token, which returns {"securityToken": "TOKEN"}
curl --request POST \
  --url https://SERVICE_URL/token \
  --header 'Content-Type: application/json' \
  --data '{
    "Username": "USERNAME",
    "Password": "PASSWORD"
}'
  1. Call secured endpoint
curl --request GET \
  --url https://SERVICE_URL/record \
  --header 'Authorization: Bearer TOKEN'

Is this a common authentication flow and, if so, is there a common name for it?

Can I Use Salesforce Named Credentials with this kind of flow or will I need to manually call out for the token?


Solution

  • Named Credentials cannot be used to handle this authentication flow, but the feature can be leveraged to get the token without having to resort to something like Custom Settings for storing the username & password.

    1. Create a Named Credential specifically for getting the token.

      Property Value Notes
      Label SERVICE Token Request Naming intends to specify that this is only for the token.
      URL https://SERVICE_URL/token Again, very specific to just the token call.
      Identity Type Named Principal This particular example uses the same username/password for all users.
      Authentication Protocol Password Authentication
      Username USERNAME The username required for the token request.
      Password PASSWORD The password required for the token request.
      Generate Authorization Header false If enabled, Salesforce will generate an authorization header, but the external service does not want it. The external service expects the username and password as separate properties in JSON.
      Allow Merge Fields in HTTP Body true Enabling this will allow usage of the username & password fields in apex.
    2. Anonymous Apex

    HttpRequest req = new HttpRequest();
    req.setEndpoint('callout:SERVICE_Token_Request');
    req.setMethod('POST');
    req.setHeader('Content-Type', 'application/json');
    req.setBody('{"Username":"{!HTMLENCODE($Credential.Username)}",' +
                '"Password":"{!HTMLENCODE($Credential.Password)}"}');
    
    
    Http http = new Http();
    HTTPResponse res = http.send(req);
    Map<String, Object> response = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
    String securityToken = (String)response.get('securityToken');
    System.debug(securityToken); // TOKEN