Loading
Identificazione degli utenti e gestione degli accessi
Creazione di una classe Apex di handler exchange token

Creazione di una classe Apex di handler exchange token

Un handler exchange token è costituito da una classe Apex che estende la classe astratta Oauth2TokenExchangeHandler e da una definizione di handler exchange token. Per iniziare, creare una classe Apex a cui fare riferimento nella definizione dell'handler.

Versioni (Edition) richieste

Disponibile in: Enterprise Edition, Performance Edition, Unlimited Edition e Developer Edition
Nota
Nota È possibile saltare questo passaggio generando automaticamente un modello di classe Apex quando si definisce un handler in Imposta. Assicurarsi di personalizzare l'handler generato automaticamente.
  1. Da Imposta, nella casella Ricerca veloce, immettere Apex e quindi selezionare Classi Apex.
  2. Fare clic su Nuovo.
  3. Creare una classe Apex che estenda la classe astratta Auth.Oauth2TokenExchangeHandler.
    Ecco come si presenta la classe astratta. Contiene due metodi. Utilizzare il primo metodo per convalidare il token in entrata dal provider di identità. Utilizzare il secondo metodo per mappare l'oggetto del token a un utente 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;
        }
    }
    Di seguito è riportato un esempio di implementazione che estende la classe astratta Auth.Oauth2TokenExchangeHandler.
    Importante
    Importante Questo esempio di codice è solo a scopo dimostrativo. Utilizzarlo come punto di partenza, ma assicurarsi di valutarlo, personalizzarlo e testarlo con attenzione.
    /*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;   
        }
    }
  4. Salvare la classe.
  5. Quando si è pronti, personalizzare i metodi di convalida e di mappatura degli oggetti per la classe. A seconda del processo di sviluppo, questo passaggio si può eseguire al termine della creazione dell'handler.

Per completare la creazione dell'handler, definire un handler exchange token. È possibile definire l'handler in Imposta o utilizzare l'API dei metadati.

Per ulteriori informazioni sulla personalizzazione dell'handler Apex, vedere le risorse seguenti.

 
Caricamento
Salesforce Help | Article