Salesforce SSO Instructions

Salesforce configuration intro

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.

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

You will likely need Admin privileges in Salesforce to complete all the steps below.

Step 1: Enable Salesforce SSO in KnowledgeOwl

First, we need to enable Salesforce SSO in KnowledgeOwl and add the Salesforce Login URL.

  1. In KnowledgeOwl, go to Settings > SSO.
  2. Click on the Salesforce SSO tab near the top.
  3. Check the box next to Enable Salesforce
  4. 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. 
  5. 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".  
  6. Save those settings in KnowledgeOwl.

Step 2: Create LoginController apex class in Salesforce

Now we'll begin setting up the Salesforce components. For all Salesforce steps, you'll need to be in the Setup portion of Salesforce.

  1. In Salesforce, go to Setup > Custom Code > Apex Classes.
  2. 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.
  3. 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/sf-reader-create');
            req.setMethod('POST');
            req.setBody('timestamp='+timeStamp+'&hash='+md5String+'&ssoid='+UserInfo.getUserId()+'&username='+activeUser.Email+'&first_name='+UserInfo.getFirstName()+'&last_name='+UserInfo.getLastName()+'&groups='+reader_groups);
            req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
            req.setCompressed(false);
            
            res = http.send(req);
            return res;
        }
    }
  4. Replace YOUR_KO_REMOTE_AUTH_TOKEN with your KnowledgeOwl token found under Settings > SSO > Salesforce SSO > KO Auth Token
  5. Replace SF Group1,SF Group2 with either a list of hard-coded groups you'd like to add your reader to or a field that stores that information.
  6. Replace YOUR_KO_URL with the URL of your knowledge base's home page. Our domain is "support.knowledgeowl.com/help" so that's what we would use:
  7. Once you're done updating those fields, Save the apex class in Salesforce.

Step 3: Add the Remote Site in Salesforce

Next, we need to add the knowledge base URL as an allowed Remote Site in Salesforce. To do so:

  1. In Salesforce, navigate to Setup > Security > Remote Site Settings.
  2. Click on New Remote Site.
  3. For the URL, use your knowledge base's home page URL with the /help, /home, or /docs removed. So for our site, we'd use https://support.knowledgeowl.com:
  4. Be sure to save your changes.

Step 4: Create a Visualforce page in Salesforce

For this step, you'll need to find your Develop > Pages settings in Salesforce.

Depending on your account, this may be in several places:

  • Setup > Custom Code > Visualforce Pages
  • Setup >  Build >  Develop >  Pages
  • General Account Settings >  App Setup >  Develop >  Pages (only for much older accounts)

Once you've found this option:

  1. Create a new Visualforce page.
  2. 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. 
  3. 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/sf-remote-login';
    
     koURL += '?external_id=' + escape('{!$User.Id}'
);
     
koURL += '&timestamp={!timeStamp}';
     koURL += '&hash={!md5String}';
     koURL += '&r={!redirect}';
    
     window.location = koURL;
     </script>
    </apex:page>
  4. Replace YOUR_KO_DOMAIN with your KnowledgeOwl knowledge base home page. Our home page is "https://support.knowledgeowl.com/help" so we would replace "YOUR_KO_DOMAIN" with "support.knowledgeowl.com/help":
  5. Save.

Once you've created the Visualforce page, you'll need to open the Security settings for the Visualforce page you just created.

You will need to navigate back to the menu option you used to open Pages above--if you're using Setup > Custom Code > Visualforce Pages the Security link will appear to the left of the Visualforce page name when you're viewing the list of pages.

  1. Open the Security settings for the Visualforce page you just created.
  2. Add the user profiles you wish to be able to use this integration. This will depend on your Salesforce configuration.
  3. Save those changes.

Step 5: Create final apex classes in Salesforce

Now, you can create the final two apex classes needed for the integration. To do so:

  1. Navigate back to Setup > Custom Code > Apex Classes.
  2. Create another new Apex class.
  3. 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;
        }
    }
  4. Finally, create one last Apex class. 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());     
        }
    }
  5. Once you have saved that class, click the Run Test button to ensure that your new Apex classes have full code coverage and are ready to deploy to your production environment.
  6. 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.