4

After reading Force.com Canvas Developer's Guide, I don't think I have figured out a good way to integrate an external web app inside salesforce.com. Following are questions that I am not sure about. Any advice would be much appreciated.

The ideal solution for me is I can create a web tab inside salesforce.com and attach a Canvas app there. For the first time, the user needs to authorize the web app and then the web app could figure out what to show based on the requested context using the access token. The server side of the web app could save access token for later use so the user doesn't need to authorize the web app every time he tries to access the new tab added.

Init Authentication Flow: Using OAuth, it seems there is no way to show the salesforce authentication dialog on the same page as the authentication page set x-frame-options to DENY. So I have to use the popup window to present the authentication dialog. Once the user clicks the button, salesforce will redirect the page to my callback address and I need to get the token from the url hash in that callback page. Once I get the hash, I have to manually send it back to my app redirect page using Canvas api childWindowUnloadNotification so that the redirect page could send the token to the server side and then close the popup window automatically.

At this moment, I could redirect the user to the main page of the web app. But how could I make this page secured (I don't want to ask the user to log in this external web app again using some other username and password.)? I need to get a unique identifier for the user and associate this ID with the access token I have saved on the server side. Should I query the user email as the ID and send it together with the token to the server side? And I need to save user email in the cookie so next time the user tries to access the same tab, I can figure out whether this user has valid access token on the server and authorize the access to the main page of external web app directly.

I am not sure whether I missed anything so that this implementation in my mind looks a little bit complicated. Anyone has experience in similar projects please help. Thanks in advance!

Regards,

Sheng

Update Maybe people won't see the last comment from @sfdcfox directly on the screen. I should have mentioned the web application I am going to integrate is pure client-side rendering at the very beginning. Using the web server auth flow is the way I have implemented so far and everything works well. In order to easily get my application session integrated, I have created a custom field named application_user_name inside User entity and my application is going to query that field and create corresponding session for the Salesforce user. Now I can store the refresh token on the server and ask for access token again when needed. The application has been seamlessly integrated. Thanks for all the comments and answers!

  • In this case SF is authorization server. You will register your app as an connected app. Set up custom APEX page that will be in IFRAME and will fire your app page for initiation of the OAuth 2.0 handshake. After log on SF, your user will be asked to confirm that data will be used on shes behalf from your app. In backend OAuth 2.0 will be finished and you will have access token as unique user's identifier. – Rastko Jan 8 '14 at 18:30
  • @Rastko, Thank you very much for the quick reply! I did add my app as a connected app. I chose tab instead of VisualForce page as I don't need to figure out all the parameters for apex:page and apex:canvasApp. For example, I don't need to find parameter that I could use to hide the left sidebar. Tab + CanvasApp seem to be a weird way to integrate application. – Sheng Jan 8 '14 at 20:37
  • @Rastko, Initially I don't want to create server side service to handle the OAuth callback. Is that what you have described in your comment, the Web Server Flow? I am actually trying to use the User-Agent flow. My question is still around controlling execution of Sfdc.canvas.oauth.login(). I only want to execute it once at the first time the user accesses the application. If refresh token could be indefinite, I could save it on server side and associate it with specific user id. So next time, if the server says for this user token is available, I can skip the login on salesforce side. – Sheng Jan 8 '14 at 21:00
4

Canvas apps are sent an authentication token automatically after being authorized by the user; this all occurs on the salesforce.com servers, and your app isn't involved until it receives a valid authentication token.

You can query for the user ID if you need to store per-user data; the ID is guaranteed to be unique, while the email address may not be. The user won't have to authorize the application each time, since each time the tab is loaded a new token will be sent to the application server.

It would probably be worthwhile to visit Heroku and create a sample canvas app so you can get a feel for how it behaves. A single worker thread is free (750 dyno hours per month), so you can experiment with how canvas apps work before starting your own application development.

You are not provided with a refresh token using OAuth2 authentication, so it is recommended that you used a signed request model instead. You should take a look at the authentication section in the Canvas Framework Developer's Guide.

  • thanks a lot for your answer and suggestions. A few questions: for creating a Canvas app, we still need to use Sfdc.canvas.oauth.login to trigger the authorization popup window, right? – Sheng Jan 8 '14 at 21:09
  • another question, I don't quite understand "The user won't have to authorize the application each time, since each time the tab is ...". My understanding for the authentication process is I will check on the server side to see if we have valid token for this specific user. If yes, the app is going to process to the main page. If not, the app is going to call Sfdc.canvas.oauth.login again in order to get a valid token. – Sheng Jan 8 '14 at 21:18
  • I looked at the signed request model initially but I just wanted to create a quick prototype of the integration so I chose the User-Agent OAuth Authentication Flow as only client side implementation is needed. Maybe that was a wrong decision. One more question, for signed request authentication, does the user only have to authorize once for the Canvas app? – Sheng Jan 8 '14 at 21:33
  • @Sheng For either model, you only need to authorize once. Once authorized, salesforce.com remembers this authentication and goes to "immediate" mode, where salesforce.com doesn't actually prompt the user, but instead automatically returns an authentication token. – sfdcfox Jan 8 '14 at 21:58
  • 1
    @Sheng It is true that tokens expire, and so therefore it may need to refresh that token from time to time. As specified in the documentation, OAuth2 doesn't get a refresh token in a canvas app, so that means the user would be required to eventually reload the tab (2 hours by default, but configurable between 15 minutes and 12 hours). Signed requests are authorized by the administrator by installing the app, so there's no need for any prompt at all. – sfdcfox Jan 8 '14 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.