Controller REST personalizzato per accedere a Auth.AuthToken.getAccessToken che restituisce null
A seguito di una domanda precedente:
- Come accedere al token OAuth archiviato in NamedCredential utilizzando Apex per l'utilizzo in altre applicazioni di terze parti
Ho creato un endpoint REST personalizzato a cui accede tramite proxy Auth.AuthToken.getAccessToken(authProviderId, providerName);come suggerito da @identigral.
Classe controller REST Apex utilizzando 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';
}
}
}
Il controller REST è accessibile tramite a Sitee sto passando un bearer token quando chiamo l'endpoint.
La Auth. Providerconfigurazione è:
- Tipo di fornitore:
Open ID Connect - Nome:
MockLab - Suffisso URL:
MockLab - Chiave consumatore:
mocklab_oauth2 - Segreto del consumatore:
whatever - Autorizza URL endpoint:
http://weyz3.mocklab.io/oauth/authorize - URL endpoint token:
http://weyz3.mocklab.io/oauth/token - URL endpoint informazioni utente: vuoto
- Emittente del token: vuoto
- Ambiti predefiniti: vuoto
- Invia token di accesso nell'intestazione:
true - Invia le credenziali del cliente nell'intestazione: false
- Includi il segreto del consumatore nelle risposte dell'API:
true - URL di errore personalizzato: vuoto
- URL di disconnessione personalizzato: vuoto
- Gestore della registrazione: vuoto
- Esegui registrazione come: vuoto
- Portale: vuoto
- URL icona: vuoto
La NamedCredentialconfigurazione è:
- Etichetta:
MockLab - Nome:
MockLab - URL:
https://weyz3.mocklab.io/ - Certificato: vuoto
- Tipo d'identità:
Named Principal - Protocollo di autenticazione:
OAuth 2.0 - Provider di autenticazione:
MockLab - Scopo:
openid, profile, email - Stato di autenticazione:
Authenticated - Genera intestazione autorizzazione:
true - Consenti campi unione nell'intestazione HTTP: false
- Consenti campi unione nel corpo HTTP: false
- Connessione di rete in uscita: falso
Ho completato il OAuthflusso, in modo che il NamedCredentialha un Authentication Statusdi Authenticated.
Ho anche testato i NamedCredentiallavori collegandomi all'API esterna e recuperando alcuni dati utilizzando Apex.
Ma quando chiamo il mio endpoint REST personalizzato per ottenere il token di accesso, ottengo sempre un nullvalore.
Risposta di esempio:
{
"Username" : "[email protected]",
"Name" : "Admin User",
"AuthProviderId" : "0SO4K000000GozdWAC",
"AccessToken" : null
}
In base alla risposta, posso vedere che la richiesta è stata autenticata correttamente utilizzando il token di trasporto.
Ma la chiamata a Auth.AuthToken.getAccessToken(authProviderId, providerName);sta ancora tornandonull
Se provo a eseguire questo codice nella console per sviluppatori:
String token = Auth.AuthToken.getAccessToken('0SO4K000000GozdWAC', 'Open ID Connect');
System.debug(token);
Ottengo un nullvalore.
Ho provato a chiamare il metodo tramite un componente LWC:
@AuraEnabled(cacheable=true)
public static String getAccessToken() {
return Auth.AuthToken.getAccessToken('0SO4K000000GozdWAC', 'Open ID Connect');
}
Ottengo un nullvalore.
Tutto viene eseguito utilizzando lo stesso utente amministratore.
AGGIORNAMENTO: Ho modificato i dettagli Auth. Providere Named Credenitalai valori effettivi per un MockLabambiente che ho configurato, in modo da poter testare utilizzando esattamente le stesse informazioni / configurazione che sto utilizzando.
Domande
- Che cosa sto facendo di sbagliato?
- Come posso risolverlo, in modo che il controller restituisca il token?
Risposte
Modificato
Ho eseguito alcuni test con il tuo codice e la configurazione in un'organizzazione per sviluppatori,
Test 1: accedi come l'utente che ha creato l'Auth. Fornitore in Workbench
Risultato: posso ottenere il token nel banco di lavoro.
Test 2: concedi l'accesso di classe apex a un sito e visita il sito
Risultato: ho ottenuto un nullcome utente del sito.
Test 3: accedere come un altro amministratore di sistema in Workbench
Risultato: ho ottenuto un file null
Immagino che solo l'utente creato Auth. Providerpossa ottenere il token usandoAuth.AuthToken.getAccessToken(authProviderId, providerName);
Puoi confermare che il nome utente nella tua risposta di esempio è uguale al nome utente dell'amministratore Salesforce che ha creato il provider di autenticazione?
Ho creato un'app connessa e ho ricevuto un token dell'utente corrente
quindi ho utilizzato il token utente per chiamare l'API rest e sono riuscito a ottenere AccessToken in Postman.
Sebbene sia possibile ottenere correttamente il token, questo introduce un nuovo token.