Problem Statement
I am working on an integration that will authenticate with a token. I need to pass it via header as follows:
"Authorization": "Token abcdefghijklmnopqrstuvwxyz"
I also need to merge some data into the endpoint. I have considered the following options for storage of the token(s):
- Custom Setting
- Custom Object
- Custom Metadata Type
- Named Credential
My main question is if it is possible/reasonable to use Named Credentials
to store tokens.
Assessment
Custom Setting
Simple, lightweight, and flexible, this approach is the easiest to get off the ground.
Pros
- Does not require any query to access the data
- Only Users with
Customize Application
can see the data - Anyone can access the data via
Apex
when making the callout - Can configure to store any desired authentication mechanism
Cons
- No encryption (?)
Custom Object
If encryption of the token is critical, we could roll out a Custom Object
to store our tokens. This seems like a really ham-handed approach and I would like to avoid it if at all possible
Pros
- Flexible configuration
- Encryption
Cons
- All users need read access or the code needs to run
without sharing
- Requires a query to access the data
Custom Metadata Type
This option doesn't really seem to have any advantages over using a Custom Setting
or Custom Object
.
Pros
- Flexible configuration
Cons
- No Encryption
- Requires a query to access the data
Named Credentials
This option seems really promising, but based on my reading so far, it's not clear to me if it has the flexibility I need. After navigating to Setup
> Administration
> Security Controls
> Named Credentials
and clicking on the New Named Credential button, I got this screen:
Setting the Authentication Protocol
to Password Authentication doesn't seem like a good fit, but it was hard to hunt down how to set up an Authentication Provider
. It doesn't seem to actually be a field on the NamedCredential
object (the only lookup fields in the describe are CreatedById
and LastModifiedById
).
I found an article that purports to describe how to Create a Custom External Authentication Provider, but its description of how to navigate to the setup is outdated. It recommends:
From Setup, enter Auth. Providers in the
Quick Find
box, then select Auth. Providers.
There's no such item in my setup menu. The closest I could find was Identity Provider
, which requires me to set up My Domain
before I can use it. This option seems like it has way more side effects than I would like.
Pros
- Purpose built for authentication procedures
Cons
- Unclear if it supports token authentication
- Unclear if it supports merging data into the URL
- Requires
My Domain
(?)
Questions
- Can
Named Credentials
be used to support token based authentication?- Is it necessary to set up
My Domain
in order to do so?
- Is it necessary to set up
- Is there really any worry about standard users seeing the token values?
- If stored in a
Custom Setting
, only users with theCustomize Application
permission can access the data through the UI. These users should be highly trusted already.
- If stored in a
- Is there any benefit to encrypting the token?
Best Answer
Your assessments are pretty close, but you've got some glaring errors I'd like to bring up.
Custom Settings / No Encryption?
You can encrypt the token using the Crypto class if you need to. Just because it doesn't support the Text (Encrypted) data type doesn't mean it's impossible.
Custom Metadata Type / Requires Query
In addition to the same comment about Custom Settings, Custom Metadata does require a query, but these queries do not count against governor limits at all (SOQL row/query limits do not increment). The major con that you missed, though, is that you cannot update a Custom Metadata entry via Apex Code directly, but instead have to leverage a metadata API call instead. This makes it non-trivial to implement in Apex Code/Visualforce/Lightning because of the extra hoops for simply storing a token.
No Auth. Provider
In Lightning Experience, it's under Identity > Auth. Providers, and in Salesforce Classic, it's under Security > Auth. Providers. In either case, you need the Manage Auth. Providers permission. Check your profile settings if you're on a custom profile, or create a permission set for yourself.
Questions
Yes, that's one of the primary benefits of using Named Credentials.
No, I just set up a Facebook OAuth2 connection in a dev org without My Domain configured, so it's clearly not necessary.
Technically, you should treat the token the same as a password. That said, most users in your system wouldn't know what to do with a token if you told them how to use it, the few that do are probably developers that need to be trusted with these tokens anyways, and anyone that intends harm shouldn't even be an employee, much less someone that can log in with enough permission to see the token.
In a typical org, there's little need to encrypt the token. As a bonus, Named Credentials seems to store the token in a place that can't be accessed even by admins (not that I could see anywhere), so using NC limits interactions to just programmed interactions and, for developers and admins, execute anonymous scripts. I would personally recommend NC as the preferred form of authentication.
Closing Notes
Named Credentials are purpose-built for OAuth authentication, and should be the preferred means of doing so over all other means. The other techniques exist primarily because they were invented by thousands of developers independently, which salesforce.com obviously noticed, and decided to provide a standardized interface for us to use.
Identity Provider configuration allows salesforce.com to act as an Identity Provider, which means you could log in to services like Twitter, Facebook, or your internal apps using your salesforce.com user login. It's not used for outbound authentication at all.