Print this page

Delegated Authentication in Identity Connect

Knowledge Article Number 000230436
Description
Learn how to use Identity Connect as a Delegated Authentication Gateway, the steps to achieve Delegated Authentication and the specific URL used. 
Resolution
You'll need to include an Apex Classes to your Organization, which can transform the Salesforce Delegated Authentication call into the REST Format used by Identity Connect.


Delegated Authentication Service


This is a simple Delegated Authentication Service. Follow these steps: 


 
1. Please copy the code and create Delegated Authentication Service in the org.
2. Configure the code so it points at your Identity Connect server. Make sure that it can get through any firewalls!
3. In a Site, or in the force.com Site that underlies your Community, we need to enable the Site profile for this ApexClass. This will expose an anonymous web service. 
4. Create a case with Salesforce Support to enable Delegated Authentication.
5. After getting it enabled, we need to configure the Delegated Authentication URL on Single Sign-On Settings as: https://YOUR_SITE_OR_COMMUNITY_URL/services/apexrest/delegatedauth
6. Assign the Is Single Sign-On Enabled permission to any Users you'd like to use Delegated Authentication. 


 

Apex Class for Delegated Authentication Service

 
@RestResource(urlMapping='/delegatedauth/*')
global with sharing class DelegatedAuthService {
    
    static final Blob AUTH_TRUE = Blob.valueOf('<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><AuthenticateResponse xmlns="urn:authentication.soap.sforce.com"><Authenticated>true</Authenticated></AuthenticateResponse></soapenv:Body></soapenv:Envelope>');
    static final Blob AUTH_FALSE = Blob.valueOf('<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><AuthenticateResponse xmlns="urn:authentication.soap.sforce.com"><Authenticated>false</Authenticated></AuthenticateResponse></soapenv:Body></soapenv:Envelope>');
    
    static final String IDENTITY_CONNECT = 'https://YOUR_HOST_AND_PORT/openidm/info/login';
    
    @HttpPost
    global static void doPost() {
    
        Blob responseBody = AUTH_FALSE;
        
        RestRequest req = RestContext.request;
        Dom.Document doc = new Dom.Document();
        doc.load(req.requestBody.toString());
        Dom.XMLNode authRequest = doc.getRootElement();
        
        Dom.XMLNode body = authRequest.getChildElement('Body', 'http://schemas.xmlsoap.org/soap/envelope/');
        Dom.XMLNode authenticate = body.getChildElement('Authenticate', 'urn:authentication.soap.sforce.com');
        String username = authenticate.getChildElement('username', 'urn:authentication.soap.sforce.com').getText();
        String password = authenticate.getChildElement('password', 'urn:authentication.soap.sforce.com').getText();
        String sourceIp = authenticate.getChildElement('sourceIp', 'urn:authentication.soap.sforce.com').getText();
                    
        Http h = new Http();
        HttpRequest hr = new HttpRequest();
        hr.setEndpoint(IDENTITY_CONNECT);
        hr.setHeader('X-OpenIDM-Username',username);
        hr.setHeader('X-OpenIDM-Password',password);
        hr.setMethod('GET');
        HttpResponse hrs = h.send(hr);
        if (hrs.getStatusCode() == 200)  {
            responseBody = AUTH_TRUE;
        } 

        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/soap+xml');
        res.statusCode = 200;
        res.responseBody = responseBody;
            
    }
  
  
}
 

 

Multi-Delegated Authorization Service

 

This is a Delegated Authorization Service that can split between multiple services in case you have more than 1 Active Directory deployment. To get started:

 

1. Please copy the below class code and create Delegated AuthService in your Organization.
2. Configure the code so it points at both your Identity Connect servers. Make sure it can get through firewalls.
3. Modify the code to support the best strategy for determining which server to route users to. This implementation uses a Custom Picklist on User, but you might parse the email address and look at domain.
4. In a Site, or in the force.com Site that underlies the Community, please enable the Site profile for this ApexClass. This will expose an anonymous web service.
5. Create a case with Salesforce Support to enable Delegated Authentication.
6. After getting it enabled, we have to configure the Delegated Auth URL on Single Sign-On Settings as: https://YOUR_SITE_OR_COMMUNITY_URL/services/apexrest/multidelegatedauth
7. Assign the "Is Single Sign-On Enabled" permission to any Users you'd like to use Delegated Authorization. 


 

Apex Class for Multi Delegated Authorization

 
@RestResource(urlMapping='/multidelegatedauth/*')
global with sharing class MultiDelegatedAuthService {
    
    static final Blob AUTH_TRUE = Blob.valueOf('<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><AuthenticateResponse xmlns="urn:authentication.soap.sforce.com"><Authenticated>true</Authenticated></AuthenticateResponse></soapenv:Body></soapenv:Envelope>');
    static final Blob AUTH_FALSE = Blob.valueOf('<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><AuthenticateResponse xmlns="urn:authentication.soap.sforce.com"><Authenticated>false</Authenticated></AuthenticateResponse></soapenv:Body></soapenv:Envelope>');
    
    static final String IDENTITY_CONNECT_A = 'https://YOUR_HOST_AND_PORT_FOR_SERVER_A/openidm/info/login';
    static final String IDENTITY_CONNECT_B = 'https://YOUR_HOST_AND_PORT_FOR_SERVER_B/openidm/info/login';
    
    @HttpPost
    global static void doPost() {
    
        Blob responseBody = AUTH_FALSE;
        
        RestRequest req = RestContext.request;
        Dom.Document doc = new Dom.Document();
        doc.load(req.requestBody.toString());
        Dom.XMLNode authRequest = doc.getRootElement();
        
        Dom.XMLNode body = authRequest.getChildElement('Body', 'http://schemas.xmlsoap.org/soap/envelope/');
        Dom.XMLNode authenticate = body.getChildElement('Authenticate', 'urn:authentication.soap.sforce.com');
        String username = authenticate.getChildElement('username', 'urn:authentication.soap.sforce.com').getText();
        String password = authenticate.getChildElement('password', 'urn:authentication.soap.sforce.com').getText();
        String sourceIp = authenticate.getChildElement('sourceIp', 'urn:authentication.soap.sforce.com').getText();
        
    	List<User> users = [SELECT Id, FederationIdentifier, DelegatedAuthService__c FROM User WHERE username = :username limit 1];
        if (users.size() == 0 ) {
            isError = true;
        } else {
            User u = users.get(0);
            String delAuthService = IDENTITY_CONNECT_A;
            if ( (u.DelegatedAuthService__c != null ) && ( u.DelegatedAuthService__c == 'IDENTITY CONNECT B' ) ) delAuthService = IDENTITY_CONNECT_B;
                        
            Http h = new Http();
            HttpRequest hr = new HttpRequest();
            hr.setEndpoint(delAuthService);
            hr.setHeader('X-OpenIDM-Username',u.FederationIdentifier);
            hr.setHeader('X-OpenIDM-Password',password);
            hr.setMethod('GET');
            HttpResponse hrs = h.send(hr);
            if (hrs.getStatusCode() == 200)  {
                responseBody = AUTH_TRUE;
            } 
        }
            
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/soap+xml');
        res.statusCode = 200;
        res.responseBody = responseBody;
            
    }
  
  
}
 


 





promote demote