After writing this article Salesforce has enabled CSP (Content Security Policy) which restricts adding Salesforce in iFrame. We can add MyDomain URL as CSP whitelisting and it works only if user already logged into other Salesforce instance. However, if user is not logged into other instance , internally OAuth navigates through login.salesforce.com which is too restrictive and canvas application fails to load.
In this post we will discuss how Canvas can be used to integrate Salesforce with Salesforce. On my blog we have seen many articles and possibilities to integrate Salesforce with another Salesforce instance like this and this post.
Whats is force.com Canvas
Force.com Canvas SDK from Salesforce allows developers to connect existing legacy system or any web based application with Salesforce using JavaScript and REST API. Canvas applications can be displayed in Chatter, Salesforce Mobile Cards or Visualforce page.
Why we are accessing another Salesforce instance as Canvas app
To get hands on with Canvas, most of article are around creating Heroku applications. I understand there are few developers who are not comfortable with Heroku. So to keep learning curve less, lets use Visualforce page to be exposed as Canvas application after all Visualforce is very advance MVC framework in itself.
Note:
For this blog post, we will need two Salesforce Org. One will act as Identity provider and other will act as Service Provider. I have enabled My Domain and below are information
- https://jitendrazaa5-dev-ed.my.salesforce.com – Service Provider
- https://jitendrazaa2-dev-ed.my.salesforce.com – Identity Provider
Enable My Domain
First step is to enable My Domain in Service Provider Organization. I would suggest name your org with suffix like “spProvider” and “ipProvider” to avoid confusion.
Enable and setup SSO in Service provider Org
You can read this article for more detail on using Salesforce as IDp and SP. Assuming, you already have basic knowledge of SSO, we will jump start.
In Service provider Organization enable SSO by navigating to “Setup | Security Controls | Single Sign-On Settings”.
Download “Self Signed Certificate” from Identity provider by navigating to “Setup | Security Controls | Certificate and Key Management | Create Self Signed Certificate”.
Below image shows configuration of SSO in Service provider organization, In our case domain “jitendrazaa5-dev-ed.my.salesforce.com”.
In above image Issuer is URL of identity provider and Entity Id is URL of current org which is Service provider.
Once we informed Service provider Org that SSO is enabled on basis of federation Id, we need to make sure that Federation Id on user records on both Org must match else SSO will not work and those users will not able to use Canvas application.
Create force.com Canvas application in Identity provider Org
Navigate to “Setup | App Setup | Create | Apps | Connected Apps | New”
As you can see in above setting, Canvas application is enabled for Chatter and Mobile navigation and it uses Visualforce page of Service provider Organization.
Entity Id and ACS URL is copied from SSO settings of Service provided organization.
Creating Visualforce page using Canvas SDK in Service Provider Organization
Instead of using any Heroku or external web based application, we will be using Visualforce page with Canvas SDK. For this, we need to download Canvas SDK from this Github repository and upload it as static resource. In below Visualforce page, we are simply reading Signed request from Identity provider Organization showing capabilities of Canvas SDK as well as we are displaying SessionId, OAuth token and refresh token of Service provider Organization.
As Canvas application is configured to view from Chatter tab, Output will look like :
Source code for Canvas in Salesforce
<apex:page showHeader="false">
<script type="text/javascript" src="{!URLFOR($Resource.CanvasSDK,'SalesforceCanvasJavascriptSDK-master/js/canvas-all.js')}" />
<script type="text/javascript">
var sid="{!GETSESSIONID()}".substr(1,30) +'...';
function refreshSR(){
Sfdc.canvas.client.refreshSignedRequest(function(data){
if(data.status == 200){
var signedRequest = data.payload.response;
var part = signedRequest.split('.')[1];
var obj = JSON.parse(Sfdc.canvas.decode(part));
updateDisplay(obj) ;
}
});
}
function updateDisplay(obj){
setValue('spSessionId', sid);
setValue('ipOAuth', obj.client.oauthToken.substr(1,30)+'...');
setValue('ipUser', obj.context.user.fullName);
setValue('ipOrg', obj.context.organization.name);
setValue('ipRefresh', obj.client.refreshToken.substr(1,30)+'...');
}
function setValue(eleId,val)
{
var domEl = document.getElementById(eleId);
if(domEl){
domEl.innerHTML = val;
}
}
Sfdc.canvas.onReady(function(){
refreshSR();
});
</script>
<b> <u> Service Provider Org </u></b>
I am Canvas App from Salesforce Domain <b> Jitendra.zaa5@gmail.com </b>
User : {!$User.FirstName} {!$User.LastName}
Org : {!$Organization.Name}
Session Id : <span id="spSessionId"></span>
<hr />
<b> <u> Identity Provider Org - Current Org </u> </b>
User : <span id="ipUser"></span>
Org : <span id="ipOrg"></span>
OAUth Token : <span id="ipOAuth"></span>
Refresh Token : <span id="ipRefresh"></span>
</apex:page>
Leave a Reply