I'm trying to write Apex code that'll call an external API. The API is using OpenID Connect for authentication, meaning I'll have to first give consent in order to get an authorization code, then exchange that for an access token and THEN use that as Bearer token to call the actual API endpoint I want. The entire flow is described on this page: https://developer.mobilepay.dk/developersupport/openid-get-started

Normally, I would use Named Credentials for easy callouts, however in this case, the authorize- and token-steps are using PKCE code challenge, which means I'll have to add at least one extra header to calls to the authorize endpoint (the codechallenge) as well as to the later calls to the token endpoint (the codeverifier). I cannot see any way of using Named Credentials - or Auth. Providers - to do this.

I also tried looking into storing tokens in Custom Metadata, but that won't work since I cannot DML Custom Metadata and each access token is only valid for 5 minutes before expiring and needing the refresh token, so I'd need some automated way of refreshing it.

What would be the most sensible way to accomplish this? All the documentation I can find about Salesforce + OpenID is talking about how to use OpenID providers to log INTO Salesforce, but I'm attempting to go in the other direction: Using OpenID to call OUT of Salesforce to a third-party API.

1 Answer 1

  1. You'll need to roll your own client that implements the oAuth authorization code flow with PKCE extension. As you found out, Named Credential won't help you.

  2. The common wisdom is that tokens should be stored in custom settings and/or custom metadata. The latter can be updated via the Metadata API. You will also need to store the code verifier until it's redeemed for the access token, platform cache might be a good option.

We disagree with the common wisdom. Our recommendation is that tokens (and any intermediate material such as code verifier) should be managed as fields on records via a custom object. You can encrypt fields, manage access to these records based on the usual Salesforce machinery, keep the records for audit purposes and/or purge them as needed, report on them and so on.

  • The server explicitly wants the code verifier to be created from an array of bytes (and validates based on an array of bytes too as shown on developer.mobilepay.dk/node/1354 ). In PHP I could accomplish this by using pack('H*', $random) where $random = bin2hex(openssl_random_pseudo_bytes(32)), before doing the base64urlencode. As reported on developer.salesforce.com/forums/?id=906F00000008zfhIAA it does not seem like Salesforce Apex supports creating an array of bytes, and since the end result is different if using Blobs, I'm worrying I'm SOL and need to create a middleware Jul 25, 2019 at 11:48
  • It's a string first, give that a shot.
    – identigral
    Jul 25, 2019 at 15:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .