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.
{"securityToken": "TOKEN"}
curl --request POST \
--url https://SERVICE_URL/token \
--header 'Content-Type: application/json' \
--data '{
"Username": "USERNAME",
"Password": "PASSWORD"
}'
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?
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.
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. |
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