Per User Integration with Salesforce & Curity (External System)

 Problem Statement : 

We have three systems - 


  • Salesforce is Auth Provider. 
  • Curity is Identity Provider which validates the user from ADFS
  • Once user get validate, It will redirect on salesforce & as business requirement agent can consume the MS(Microservices API's) , which fetch the data from external system.

I gone through the below possible solutions - 

  1. Use Auth 2.0 Open ID Connect but as the standard of salesforce agent has to go with Manual reauthentication is required after login - Manual authentication is not user friendly for business. 
  2. Use JWT Token Exchange with Salesforce Named credential to bypass reauthentication, Curity platform is not supported as the product issue.
  3. SF and Curity can go with Client credentials which is system to system integration 
  4. Do a full customization code to achieve this Per user Integration.
We have tried with above options but get to know that in Salesforce per user Integration in OOB way is not possible. so finally we have decided to do a full code. And finally we have successfully completed the Integration with option 4. 

Pre Configuration at SF end - 
  • Required client Id & Client Secret
  • Federation Id to be set Salesforce to validate with other DB like ADFS
  • Required external system end point which can sent the access Token.
  • Required the CA signed certificate to be created in salesforce & if required it should be white listed from external system. 

Perfect code of Per user Flow - 

        String client_id = '********';
        String client_secret ='********';     
      Long exp = DateTime.now().addMinutes(30/60/24).getTime(); 

        Map<String,String> extraClaims = new Map<String,String>(); 
        extraClaims.put('nbf', DateTime.now()+'');
        extraClaims.put('iat', DateTime.now()+'');
        extraClaims.put('exp', exp+'');        
        User useObj = [select Id, UserRole.Name,FederationIdentifier from user WHERE id =:                            UserInfo.getUserId()];        
        Auth.Jwt jwt = new Auth.Jwt();
        jwt.setIss('salesforce_jwt'); 
        jwt.setAud('https://ecapit.entercard.com/oauth/v2/oauth-token');   
        jwt.setSub(useObj.FederationIdentifier+' '+useObj.UserRole.Name); 
        jwt.setAdditionalClaims(extraClaims);
        // Set the validity time for access token. 
        jwt.setValidityLength(60*60); 
        Auth.JWS jws = new Auth.JWS(jwt, 'salesforcesct'); 
        String assertion = jws.getCompactSerialization();
        String payload = 'assertion=' + assertion+'&grant_type=' + System.EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer', 'UTF-8')+  
        '&client_id='+client_id+'&client_secret='+client_secret+'&scope=um_admin profile email';
        
Http httpObj = new Http();
HttpRequest req = new HttpRequest();
HttpResponse res;
req.setEndpoint('https://ecapit.entercard.com/oauth/v2/oauth-token');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setBody(payload);
res = httpObj.send(req);
system.debug('@@ response'+res.getBody());
        system.debug('@@ response'+res.getStatus()); 
        wrapObj = (Wrapper)Json.deserialize(res.getbody(),Wrapper.class);       
        accessToken = wrapObj.access_token; // we are getting access token      
        System.debug('Access Token Getting From API----'+wrapObj.access_token);       
        System.debug('Refresh Token Getting From API----'+wrapObj.refresh_token);

         public static Wrapper wrapObj {get; set;}   
        public class Wrapper{          
        String access_token;  
        String expires_in;
        String refresh_expires_in;
        String refresh_token;
        String token_type;
        String scope;
        String session_state;
    }  


Comments