8

I'm trying to determine if this is an unsupported Canvas scenario or if there's something misconfigured in the org or the browser that would otherwise allow it to succeed.

For the purpose of simplicity of this question: This canvas app is showing the user a "document viewer" widget which will be rendered in a lightning component placed on a flexipage. This widget will ultimately be raising events that can be acted upon within Salesforce.

I have a canvas app endpoint configured at https://sfdc-canvas.example.com and this endpoint authenticates the request and parses a few parameters out of the SignedRequest payload and uses the values to redirect the iframe to https://docviewer.example.com.

Problem

When this canvas app is rendered, the browser console displays the message below, indicating that something prevented a message from being posted to the canvas frame because the frame's URL doesn't match what is configured on the Connected App's Canvas URL.

CanvasProxy.js:29 (this is the location of window.postMessage(a, b))

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://sfdc-canvas.example.com') does not match the recipient window's origin ('https://docviewer.example.com').

It appears that when messages are posted to/from the canvas app to Salesforce via postMessage, the only supported origin is the one explicitly defined on the Connected Application.

  1. Is it forbidden to communicate with hosts, all on the same domain, through canvas eventing, other than the one explicitly set in the connected app?
  2. Can I use a canvas app embedded in a VF page, which is then embedded in a lightning component to work around this restriction? (rather than using the force:canvasApp tag directly in the LC)

I came across this related question, noting that this security restriction was put in place with the Winter '16 release, however this doesn't address the use case of the canvas app being rendered from a different origin than the value explicitly stated in the Connected App.

Diagram

A sequence diagram, if the above could be clarified with a picture. enter image description here

3rd Party App Configuration

The remote "document viewer" canvas app has markup similar to this, to publish an event back to Salesforce to trigger the opening of the targeted document using the Canvas SDK library:

Sfdc.canvas(function() {
    sr = JSON.parse('<%=signedRequestJson%>');
    Sfdc.canvas.client.publish(sr.client,
        { 
            name : "myNS.openDocument", 
            payload : { 
                documentId : 'someID',
                documentType: 'T1'
            }
        });
});

Update:

I now suspect that the problem is originating within the SDK's publishing of the event from the 3rd party and the sr.client value containing the original Canvas endpoint as the origin and not the URL of the "document viewer" host which it is actually being rendered from.

Sfdc.canvas.client.publish(sr.client

Update 2:

Looks like it is not the publishing of an event (Sfdc.canvas.client.publish() where the error is logged out to the console, it is when the Sfdc.canvas(function() { is being called.

The org-side of this onready-like behavior is where the postMessage is being called within CanvasProxy.js and rejected because of the origin mismatch.

Removing the Sfdc.canvas(callbackFn); might be a temporary workaround but definitely not a solid solution.

Update 3:

The removal of the Sfdc.canvas() function did nothing to better the situation. Looks like it is the call to Sfdc.canvas.client.refreshSignedRequest() which we are executing on init from the script at docviewer.example.com that triggers this error message.

I may end up using a new service hosted at sfdc-canvas.example.com as a relay/proxy to refresh the signed request payload on my behalf from the other host.


I would love some advice if anyone has implemented a canvas app where the domain of the rendered app is different than the domain of the canvas URL.

This use case is similar to the shared usage of login.salesforce.com by all users of the platform and then the My Domain vanity URLs representing a custom instance for one specific client.

I do not want to completely abandon Canvas and use raw iframes and I also prefer to leverage the Canvas SDK where I can - maybe this cross frame messaging is not one of those places.

1
  • Did you find solution to your problem. I am having similar problem in my managed package as well. I am trying to redirect to different domain from my connected app, callback url.
    – lambad
    Commented Jun 14, 2019 at 10:19

1 Answer 1

3

Messaging to a different origin is not supported by the Canvas SDK. You can navigate to different endpoints on the same origin, but not different origins.

Is it forbidden to communicate with hosts, all on the same domain, through canvas eventing, other than the one explicitly set in the connected app?

Any difference in subdomain or port number is a different "origin", and will block messaging.

Can I use a canvas app embedded in a VF page, which is then embedded in a lightning component to work around this restriction? (rather than using the force:canvasApp tag directly in the LC)

I believe you'll face the same restriction here. The Canvas messages will be blocked in the same way.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .