Following on from a previous question:
I've created a custom REST endpoint which proxies access to Auth.AuthToken.getAccessToken(authProviderId, providerName);
as suggested by @identigral.
Apex REST controller class using API v49.0
@RestResource(urlMapping='/AccessToken/*')
global with sharing class AccessTokenRESTController {
@HttpGet
global static void getAccessToken() {
try {
String token = Auth.AuthToken.getAccessToken(authProviderId, providerName);
System.debug(token);
if (token == null) {
RestContext.response.statusCode = 404;
RestContext.Response.responseBody = Blob.valueOf('Unable to find token for authProviderId: ' + authProviderId);
//return; // commented out for debugging
}
AccessTokenInfo info = new AccessTokenInfo();
info.AuthProviderId = authProviderId;
info.AccessToken = token;
RestContext.Response.addHeader('Content-Type', 'application/json');
RestContext.Response.statusCode = 200;
RestContext.Response.responseBody = Blob.valueOf(JSON.serializePretty(info));
} catch (Exception error) {
System.debug(LoggingLevel.ERROR, error);
throw error;
}
}
public class AccessTokenInfo {
public String Name {
get {
return UserInfo.getName();
}
}
public String Username {
get {
return UserInfo.getUsername();
}
}
public String AccessToken { get; set; }
public String AuthProviderId { get; set; }
}
private static String authProviderId {
get {
List<AuthProvider> providers = [SELECT Id FROM AuthProvider WHERE DeveloperName = :authProviderDeveloperName];
if (providers.size() == 0) {
throw new CustomException('Unable to find an Auth. Provider with DeveloperName: ' + authProviderDeveloperName);
}
System.debug(providers);
return providers[0].Id;
}
}
private static String authProviderDeveloperName {
get {
return 'MockLab';
}
}
private static String providerName {
get {
return 'Open ID Connect';
}
}
}
The REST controller is accessible via a Site
and I am passing a bearer token when I call the endpoint.
The Auth. Provider
configuration is:
- Provider Type:
Open ID Connect
- Name:
MockLab
- URL Suffix:
MockLab
- Consumer Key:
mocklab_oauth2
- Consumer Secret:
whatever
- Authorize Endpoint URL:
http://weyz3.mocklab.io/oauth/authorize
- Token Endpoint URL:
http://weyz3.mocklab.io/oauth/token
- User Info Endpoint URL: blank
- Token Issuer: blank
- Default Scopes: blank
- Send access token in header:
true
- Send client credentials in header: false
- Include Consumer Secret in API Responses:
true
- Custom Error URL: blank
- Custom Logout URL: blank
- Registration Handler: blank
- Execute Registration As: blank
- Portal: blank
- Icon URL: blank
The NamedCredential
configuration is:
- Label:
MockLab
- Name:
MockLab
- URL:
https://weyz3.mocklab.io/
- Certificate: blank
- Identity Type:
Named Principal
- Authentication Protocol:
OAuth 2.0
- Authentication Provider:
MockLab
- Scope:
openid, profile, email
- Authentication Status:
Authenticated
- Generate Authorization Header:
true
- Allow Merge Fields in HTTP Header: false
- Allow Merge Fields in HTTP Body: false
- Outbound Network Connection: false
I've completed the OAuth
flow, so the NamedCredential
has an Authentication Status
of Authenticated
.
I've also tested the NamedCredential
works by connecting to the external API and fetching some data using Apex.
But when I call my custom REST endpoint to get the access token, I always get a null
value.
Example response:
{
"Username" : "[email protected]",
"Name" : "Admin User",
"AuthProviderId" : "0SO4K000000GozdWAC",
"AccessToken" : null
}
Based on the response, I can see the request has successfully authenticated using the bearer token.
But the call to Auth.AuthToken.getAccessToken(authProviderId, providerName);
is still returning null
If I try running this code in the developer console:
String token = Auth.AuthToken.getAccessToken('0SO4K000000GozdWAC', 'Open ID Connect');
System.debug(token);
I get a null
value.
I've tried calling the method via a LWC component:
@AuraEnabled(cacheable=true)
public static String getAccessToken() {
return Auth.AuthToken.getAccessToken('0SO4K000000GozdWAC', 'Open ID Connect');
}
I get a null
value.
Everything is done using the same Admin user.
UPDATE: I've changed the Auth. Provider
and Named Credenital
details to the actual values for a MockLab
environment I have set up, so you can test using exactly the same information/setup I am using.
Questions
- What am I doing wrong?
- How can I fix it, so the controller returns the token?