Crear una clase de Apex de controlador de intercambio de tokens
Un controlador de intercambio de tokens consiste en una clase de Apex que amplía la clase abstracta Oauth2TokenExchangeHandler y una definición de controlador de intercambio de tokens. Para empezar a trabajar, cree una clase Apex a la que hacer referencia en la definición del controlador.
Ediciones necesarias
| Disponible en: Enterprise Edition, Performance Edition, Unlimited Edition y Developer Edition |
Nota Puede omitir este paso generando automáticamente una plantilla de clase Apex cuando defina un controlador en Configuración. Asegúrese de personalizar el controlador generado automáticamente.
- Desde Configuración, en el cuadro Búsqueda rápida, ingrese Apex y, a continuación, seleccione Clases de Apex.
- Haga clic en Nuevo.
-
Cree una clase de Apex que amplíe la clase abstracta
Auth.Oauth2TokenExchangeHandler.Este es el aspecto de la clase abstracta. Contiene dos métodos. Utilice el primer método para validar el token entrante del proveedor de identidad. Utilice el segundo método para asignar el asunto del token a un usuario de Salesforce.//Abstract Class that a developer must extend for a token exchange handler global abstract class Oauth2TokenExchangeHandler { //First method called in the handler //This method must be overriden by the extending class global virtual Auth.TokenValidationResult validateIncomingToken(String appDeveloperName, Auth.IntegratingAppType appType, String incomingToken, Auth.OAuth2TokenExchangeType tokenType) return null; } //Second method called in the handler //This method must be overriden by the extending class global virtual User getUserForTokenSubject(Id networkId, Auth.TokenValidationResult result, Boolean canCreateUser, String appDeveloperName, Auth.IntegratingAppType appType) { return null; } }A continuación se incluye un ejemplo de implementación que amplía la clase abstractaAuth.Oauth2TokenExchangeHandler.
Importante Esta muestra de código es solo para demostración. Utilícelo como un punto de inicio, pero asegúrese de evaluarlo, personalizarlo y probarlo cuidadosamente./*Token Exchange Handler Implementation Example*/ public class MyTokenExchangeClass extends Auth.Oauth2TokenExchangeHandler{ public override Auth.TokenValidationResult validateIncomingToken(String appDeveloperName, Auth.IntegratingAppType appType, String incomingToken, Auth.OAuth2TokenExchangeType tokenType) { //Depending on your incoming token, you validate it in different ways //If the incoming token is an opaque access token or refresh token, validate it with a callout to the identity provider //If it is a SAML assertion, validate it by checking the XML //If it is an ID Token or JWT, try using our JWT validation methods //The example below assumes that the incoming token is a JWT and that there is a public keys endpoint on the identity provider //Be very careful with any logic in this method and test carefully before using Boolean isValid = false; Auth.JWT jwt; //Custom data structure CustomStructuredUserData customData; //Standard user data structure Auth.UserData userData; if (tokenType == Auth.OAuth2TokenExchangeType.JWT || tokenType == Auth.OAuth2TokenExchangeType.ID_TOKEN) { try { jwt = Auth.JWTUtil.validateJWTWithKeysEndpoint(incomingToken, 'https://your-idp.com/keys', true); isValid = true; //These values would be sourced from the JWT or ID Token userData = new Auth.UserData('identifier', 'firstName', 'lastName', 'fullName', 'customer@email.com', 'link url', 'remote username', 'local', 'Provider (IDP Name)', '', new Map<String,String>()); //You can also pass data as generic object customData = new CustomStructuredUserData(); } catch (Exception e) { isValid = false; } } else if (tokenType == Auth.OAuth2TokenExchangeType.ACCESS_TOKEN || tokenType == Auth.OAuth2TokenExchangeType.REFRESH_TOKEN) { //Logic for validating a opaque access token or refresh token can go here //This validation typically involves a callout to the introspect or user info endpoints //If you call out to the user info endpoint, make sure to pass the data from the validation into the getUserForTokenSubject method using an Apex class or the user data class isValid = false; } else if (tokenType == Auth.OAuth2TokenExchangeType.SAML_2) { //Logic for validating a SAML assertion can go here //This validation involves XML parsing isValid = false; } else { //You can add new token types. If you don’t know how to validate the token, always check the type and return false isValid = false; } if(isValid){ return new Auth.TokenValidationResult(true, (object)customData, userData, incomingToken, tokenType, 'CustomErrorMessage'); } else { return new Auth.TokenValidationResult(isValid); } } public override User getUserForTokenSubject(Id networkId, Auth.TokenValidationResult result, Boolean canCreateUser, String appDeveloperName, Auth.IntegratingAppType appType) { //If you passed data from the validation method, grab it now. Remember to cast back for the custom data CustomStructuredUserData customData = (CustomStructuredUserData)result.data; Auth.UserData userData = result.userData; //If you don’t have any data from the token, you can perform a callout using the incoming token String userToken = result.token; //Now, search for a user User u; try { u = [SELECT Id, IsActive FROM User WHERE email =: userData.email]; } catch (Exception e) { //No user existed for this email address, or there were too many. Try looking harder } // If you didn’t find a user, check to see if you can create one if (canCreateUser && (u == null)) { u = new User(); u.firstName = userData.firstName; u.lastName = userData.lastName; //... Finish setting user attributes. For external users, make sure you set up the contact/account/person account //If you assign permission sets, do it in a future method to avoid mixed DML //Returning the user from this method handles the insertion, so it’s not necessary to manually insert } return u; } //This class gives you a way to pass stuctured data between the validateIncomingToken and getUserForTokenSubject methods //This example is for demonstration only. Implement this class in a way that matches the data that you are passing private class CustomStructuredUserData { public String customAttribute1; public Integer customAttribute2; public Map<String,Object> customAttribute3; } } - Guarde la clase.
- Cuando esté listo, personalice los métodos de validación y asignación de asunto de la clase. Dependiendo de su proceso de desarrollo, puede completar este paso después de finalizar la creación del controlador.
Para finalizar la creación del controlador, defina un controlador de intercambio de tokens. Puede definir el controlador en Configuración o utilizar la API de metadatos.
Para obtener más información acerca de la personalización de su controlador Apex, consulte estos recursos.
- Guía del desarrollador de Apex: Ejemplos de controlador de intercambio de tokens de OAuth 2.0
- Guía de referencia de Apex: Clase Oauth2TokenExchangeHandler
- Guía de referencia de Apex: Clase TokenValidationResult
- Guía de referencia de Apex: Clase JWTUtil
- Guía de referencia de Apex: Enumeración OAuth2TokenExchangeType
- Guía de referencia de Apex: Enumeración IntegratingAppType
¿Resolvió este artículo su problema?
¡Háganos saber cómo podemos mejorar!

