Configure Single Sign On Integration with Salesforce

Salesforce SSO will restrict access to your knowledge base to only individuals with a valid login to your Salesforce account. Readers logged in to Salesforce will be able to access your knowledge base, and anyone who tries to access your knowledge base that is not logged into Salesforce will be redirected to Salesforce to log in.

Notes: Salesforce SSO will override any other security settings such as IP address, shared password, and readers.

  1. In KnowledgeOwl, go to Settings Security  and check the box next to Enable Salesforce
  2. In Salesforce, copy the base URL for your account. On older accounts, this will look something like https://na17.salesforce.com. In newer or branded accounts, it will look like https://knowledgeowl.my.salesforce.com. 
  3. In KnowledgeOwl, paste your Salesforce URL in the field called SF login URL and add "/apex/ko_login" to the end. In the end, the entire URL will look similar to "https://na17.salesforce.com/apex/ko_login".  
  4. Save the settings.
  5. In Salesforce go to Setup → Build → Develop → Apex Classes.
  6. Create a new apex class.
    If you do not see a button to create a new apex class, you will most likely need to perform the following steps in your sandbox environment before deploying to your production instance.
  7. Copy and paste the following code into the new apex class:
    public class KnowledgeOwlLoginController {
        public string md5String {get;set;}
        public string timeStamp {get;set;}
        public string redirect {get;set;}
        private User activeUser;
        private string koToken = 'YOUR_KO_REMOTE_AUTH_TOKEN';
    
        public KnowledgeOwlLoginController () {
            String userName = UserInfo.getUserName();
            activeUser = [Select Email From User where Username = : userName limit 1];
            timeStamp = String.valueof(DateTime.now().getTime() / 1000);
            redirect = ApexPages.CurrentPage().getParameters().get('r');
            String hash = UserInfo.getUserId() + this.koToken + timeStamp;
            Blob keyblob = Blob.valueof(hash);
            Blob key = Crypto.generateDigest('MD5',keyblob);
            md5String = encodingUtil.convertToHex(key);
    
            UpsertReader();
        }
    
        //create or update the reader information in KnowledgeOwl
        public HttpResponse UpsertReader() {
            //replace static value with user specific field to pass through desired reader groups
            String reader_groups = 'SF Group1,SF Group2';
            
            HttpRequest req = new HttpRequest();
            HttpResponse res = new HttpResponse();
            Http http = new Http();
    
            //post reader information to KnowledgeOwl
            req.setEndpoint('https://YOUR_KO_URL/help/sf-reader-create');
            req.setMethod('POST');
            req.setBody('timestamp='+timeStamp+'&hash='+md5String+'&ssoid='+UserInfo.getUserId()+'&username='+activeUser.Email+'&first_name='+userFirstName+'&last_name='+userLastName+'&groups='+reader_groups);
            req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
            req.setCompressed(false);
            
            res = http.send(req);
            return res;
        }
    }
  8. Replace "YOUR_KO_REMOTE_AUTH_TOKEN" with your KnowledgeOwl token found under Settings Security  KO Auth Token.
  9. Save the apex class in Salesforce.
  10. Add the reader creation endpoint by navigating to Setup → Security → Remote Site Settings and click on New Remote Site. For the URL, use https://YOUR_KO_DOMAIN/help/sf-reader-create remembering to replace YOUR_KO_DOMAIN with your KnowledgeOwl domain.
  11. Find your Develop Pages settings in Salesforce. Newer accounts will be under Setup → Build → Develop → Pages, while in older accounts it may be under General Account Settings → App Setup → Develop → Pages.
  12. Create a new page.
  13. Specify a Label and Name.  The Label can be whatever you wish but the Name field MUST be "ko_login" in order for the integration to work. 
  14. Paste the following code in the Visualforce Markup section:
    <apex:page controller="KnowledgeOwlLoginController"><h1>Redirecting to KnowledgeOwl...</h1>
    
     <script> 
     var koURL = 'https://YOUR_KO_DOMAIN/help/sf-remote-login';
    
     koURL += '?external_id=' + escape('{!$User.Id}'
);
     
koURL += '&timestamp={!timeStamp}';
     koURL += '&hash={!md5String}';
     koURL += '&r={!redirect}';
    
     window.location = koURL;
     </script>
    </apex:page>
  15. Replace "YOUR_KO_DOMAIN" with your KnowledgeOwl knowledge base subdomain found under Settings Basic Domain. Our domain is "support.knowledgeowl.com" so we would replace "YOUR_KO_DOMAIN" with "support.knowledgeowl.com".
  16. Save.
  17. Click on Security. You may have to navigate back to Develop Pages
  18. Add the user profiles you wish to be able to use this integration.
  19. Navigate back to Setup → Build → Develop → Apex Classes and create another new Apex class with the name "MockHttpResponseGenerator".
  20. Copy and paste the following code into the apex class body and save the new class.
    @isTest
    global class MockHttpResponseGenerator implements HttpCalloutMock {
        // Implement this interface method
        global HTTPResponse respond(HTTPRequest req) {
            // Create a fake response
            HttpResponse res = new HttpResponse();
            res.setHeader('Content-Type', 'application/json');
            res.setBody('{"foo":"bar"}');
            res.setStatusCode(200);
            return res;
        }
    }
  21. Finally, create one last Apex class and name it "KnowledgeOwlLoginTest". In the body, paste the following code and save.
    @isTest
    private class KnowledgeOwlLoginTest {
        static testMethod void loginVarsTest() {
            //Set mock callout class
            Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
            
            //instantiate the controller
            KnowledgeOwlLoginController controller = new KnowledgeOwlLoginController();
            
            // Call method to test.
            HttpResponse res = controller.UpsertReader();
    
            // Verify response received contains fake values
            String contentType = res.getHeader('Content-Type');
            System.assert(contentType == 'application/json');
            String actualValue = res.getBody();
            String expectedValue = '{"foo":"bar"}';
            System.assertEquals(actualValue, expectedValue);
            System.assertEquals(200, res.getStatusCode());     
        }
    }
  22. Once you have saved the "KnowledgeOwlLoginTest" class, click on "Run Test" to ensure that your new Apex classes have full code coverage and are ready to deploy to your production environment.
  23. Test it out! When a reader tries to access your knowledge base, they must be logged in to your Salesforce account. If they are not, they will be redirected to Salesforce to log in and redirected back to your knowledge base once they are authenticated.