There is very good blog which explains steps-by-step about how Salesforce will be acting as both Identity Provider (IdP) and Service Provider (SP).
Requirement: Lets implement integration between IdP and SP. So, that whenever the User is Active/In-Active in IdP, the same thing should be reflected in the SP.
Solution: We will implement a batch job in IdP which makes a REST based callout to SP in order to create or update the users.
Step 1: Create connected App in Destination (in our case it is SP)
Step 2: Configure Client Secret, Consumer Key and the URL instance from Destination Org (SP) in Source Org (IdP)
Client Secret, Consumer Key should be configured in Custom Setting but in this example I will be directing using this in code. And the URL instance must be configured in Remote Site Settings.
Setup -> Security Controls -> Remote Site Settings
Step 3: Create a seperate Integration user in SP org and mark its profile as Password Never Expires. But in this case, we will be using admin user credentials instead of creating new integration user as we have a limit on number of licences.
Step 4:Create a custom REST based webservice in SP
@RestResource(urlMapping='/upsertuser/*') global class UserRestService { @HttpPost global static void doPatch(){ List<User> ulist = (List<User>)JSON.deserialize(RestContext.request.requestBody.toString(), List<User>.class); Database.UpsertResult[] uResult = Database.upsert(ulist, User.Fields.FederationIdentifier, true); } }
Step 5: Create a Service class which will send user data from IdP to SP
public class IntegrationService { private final String spClientId = ''; private final String spClientSecret = ''; private final String spIntegrationUName = ''; private final String spIntegrationPwd = ''; private final String spInstanceURL = 'https://playwithsf-dev-ed.my.salesforce.com'; // replace private final String spProfileId = '00e24000000zKLr'; // Chatter-free ProfileId private final String spNamespace = 'singhcloud'; //replace, if namespace is set // connecting SP from IdP public String establishConnection(){ String sessionId = ''; String reqBody = 'grant_type=password&client_id=' + spClientId + '&client_secret=' + spClientSecret + '&username=' + spIntegrationUName + '&password=' + spIntegrationPwd; Http h = new Http(); HttpRequest request = new HttpRequest(); request.setBody(reqBody); request.setMethod('POST'); request.setEndpoint(spInstanceURL + '/services/oauth2/token'); HttpResponse response = h.send(request); sessionId = fetchSessionId(response.getBody()); return sessionId; } private String fetchSessionId(String responseBody){ OAuth2 objAuthenticationInfo = (OAuth2)JSON.deserialize(responseBody, OAuth2.class); return objAuthenticationInfo.access_token; } private List<User> buildJSON(){ User usr; List<User> ulist = new List<User>(); for(User u : [SELECT Id, LastName, Username, City, PostalCode, Country, Email, IsActive, ProfileId, FederationIdentifier, Alias, TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, LanguageLocaleKey FROM User where LastModifiedDate =: Date.today() ]){ usr = new User(); usr = u.clone(false, true, false, false); usr.Username = u.Username + '.sso'; usr.ProfileId = spProfileId; // This will deactivate the User from SP when it is deactivated from IdP if(!u.isActive){ usr.IsActive = false; } ulist.add(usr); } return ulist; } public void pushUsersIntoSP(){ String sessionId = establishConnection(); if(!String.isEmpty(sessionId)){ Http h = new Http(); HttpRequest req = new HttpRequest(); req.setHeader('Authorization','Bearer '+ sessionId); req.setHeader('Content-Type','application/json'); req.setHeader('accept','application/json'); String jsonBody = JSON.serialize((buildJSON())); system.debug('json body ' + jsonBody); req.setBody(jsonBody); req.setMethod('POST'); req.setEndpoint(spInstanceURL + '/services/apexrest/' + spNamespace + '/upsertuser/'); HttpResponse response = h.send(req); } } public class OAuth2{ public String id{get;set;} public String issued_at{get;set;} public String instance_url{get;set;} public String signature{get;set;} public String access_token{get;set;} } }
Step 6: Test the service
IntegrationService conn = new IntegrationService(); conn.pushUsersIntoSP();
Do share your thoughts and happy coding!!!