9

I have a requirement to authenticate to an external API for callouts using the OAuth2 Client Credentials Grant (This was helpful in referencing the different grant types for me). I would like to use Named Credentials as I understand this is what its intended use is rather than having to handle and implement the auth flow, storing and refreshing of tokens yourself.

I haven’t found a lot to go on thus far from the docs or web searches. Looking around (here and here) it seems that this is either not possible or a bit of a hack to implement because of the need to extend the base class AuthProviderPlugin Class that expects, it seems, the Authorization Code Grant flow.

What I can gather is:

  • Named Credentials is the preferred method for authenticating and managing auth to an external API.
  • Named Credentials supports OpenId out of the box but other OAuth flows can be supported by extending the AuthProviderPlugin class.
  • The AuthProviderPlugin Class expects the OAuth implementation to use the Authorization Code Grant Flow.
  • Hence, if you are authenticating to OAuth with Client Credentials flow (or perhaps some other custom auth mechanism that requires getting a token and managing its expiration) you are left writing your own Apex to achieve this.

Are these assumptions correct? And if so, is there some convergence around (documentation, examples, open source library etc.) for managing these non-supported auth requirements?

9

In my experience, the bullet points you've highlighted are pretty much on-target. What I would add is that both NamedCredentials and CustomApplications, make the assumption the OAuth provider (the idP) has a publicly accessible Social or other major API along the lines of Facebook, Google, Twitter, etc where you can import a token or some other credential to begin with that identifies the provider. If it doesn't have that capability, it doesn't seem to want to support allowing you to do simple OAuth authentication (as in "handshaking") using protocols with some other endpoint. In essence, if you aren't doing SSO using for Salesforce Login, the Auth Namespace doesn't provide much assistance for use in OAuth custom flows that integration partners may want you to use as part of their API.

Like you, I recently found this very frustrating. See the following question Unusual OAuth JWT Bearer Token Flow (Outbound) Integration Pattern. I wound up having to write my own service to handle an OAuth Username-PW login to obtain a JWT Bearer Token, plus Refresh Token that expired after 12 hours. I couldn't find a way to make named credentials work for me and no adequate documentation to describe how to extend the AuthProviderPlugin in a manner that would allow me to do this I all could fin is Create a Custom Authentication Provider Plug-in which isn't very helpful for this type of use case (again, it assumes SSO for Salesforce login).

In examining the AuthProviderPlugin, and the Auth Namespace in general, what I've concluded is that it is almost entirely written around support for login to Salesforce and negotiation for OAuth where the idP only supports login to Salesforce; not login to other services. That generally seems to be its purpose. It is not written for OAuth negotiations for transactions that take place in the opposite direction.

Two libraries I discovered which may be helpful to you are ffhttp-core and ffhttp-core-samples. Both still expect an external provider which can include Salesforce as the idP, but are written for connecting to external services like Box (the example application illustrated in ffhttp-core-samples), GoogleDrive, etc and can be customized for any OAuth flow that you need to use. I chose not to implement ffhttp-core for my purposes, but found it helpful in figuring out what I needed to do in order to write my code.

  • Thanks for this clarification. That really helps. I have looked into the ffhttp libraries and the other examples from your question and have a class that is close to solving this now. Did you end up implementing the session management for the token? I was keen on using Custom Settings for this but the token is 800 odd chars and there is no Long Text Area field in Custom Settings. I'm currently using a custom object as the Custom Metadata API Apex deploy method seemed overly complicated for the job. – arbackhouse Jul 17 '18 at 7:20
  • I'm using custom settings for this application. I will ultimately hold some of the static settings in metadata (is still a work in progress that's nearly complete). I didn't want to have to "jump through hoops" to get code coverage in unit tests where I'd need to do DML on custom metadata as token values changed; something easily handled with custom settings. For benefit of others who might search this subject at a later time, if this post answers your question, please mark it as accepted. – crmprogdev Jul 17 '18 at 11:33

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.