Iframe based integration in Salesforce - iframe

I want to show my site inside the Salesforce iFrame, and when someone does any activity on my site inside the iFrame i want to update the Salesforce page as well?
Can i do this, please suggest?

A more recent approach, now GA, is Force.com Canvas - this is iframe-based with additional security and features, including passing context such as Salesforce fields into the iframe. It also enables the iframed web app to call Salesforce APIs based on that authentication, either via JavaScript or by your backend web app (Python, Java, etc) using the credentials from the Canvas framework.
You can also use the new Events feature within Canvas to send messages to the framing Salesforce page.
On authentication options: the Canvas Signed Request authentication is recommended and easy, but note that it doesn't give you a refresh token for OAuth2 - so if you need to do continuing background processing based on the user's authentication, you should use the Canvas OAuth2 authentication instead, which does give you a refresh token.
Overall, Canvas is cleaner than using a raw iframe and should simplify development. It does require some changes to authentication in the iframed web app but they are relatively simple (10 lines or so of Python).

You can use Javascript and page refreshing to send information to the parent window, but this isn't in my recommended books. iFrames are not meant to communicate with it's parent site for security reasons.
You might want to look into using an API to communicate between the two sites.

Related

Silent Authentication feedback from IFrame

I've read that the silent authentication is typically made in a 1px iFrame. What I've been wondering is how the response to the authentication request is passed back from the iFrame to the parent application. Only option i can think of is that the Auth-Server returns some javascript code that runs e.g.
window.top.postMessage('auth', 'thisisthetoken')
But that approach seems a little sloppy to me. So how does it work?
That is the traditional flow for token renewal in Single Page Apps. The initial authentication should be done on a main browser window via a redirect, eg as for Google Sign In or Office 365.
TOKEN RENEWAL LIBRARY USAGE
The oidc client library is commonly used to implement this, enabling the iframe post to be done with very little code.
IFRAME MECHANICS
The main window triggers an OpenID Connect redirect on a hidden iframe. When a response is received, the iframe uses the postMessage API to return an OpenID Connect response to the main window, containing code and state parameters. The main window then exchanges the code for tokens, using a PKCE code verifier that it saved to session storage before triggering the iframe redirect.
BROWSER SUPPORT FOR THIRD PARTY COOKIES
The above flow relies on the Authorization Server's SSO Cookie being sent in the iframe request, but browsers are starting to drop third party cookies to limit tracking - Safari already does this.
Therefore it is now standard to instead manage renewal via a secure cookie issued for the site of the web origin, and to avoid iframe post solutions.
Projects that rely on third party cookies these days will struggle - see this recent answer of mine.
HOSTING PREREQUISITES
In 2021 you are best to use secure SameSite cookies in the browser, since posting tokens between frames is vulnerable to Cross Site Scripting. Ensuring that the web origin of each frame can share a secure cookie via a child / sibling domain is therefore a prerequisite - you cannot really develop a secure web solution these days without it.
Security in the browser is a tricky topic and needs an architectural design - for more info on 2021 web security recommendations, take a look at recent Curity Web Guidance.
WITH TOKENS ONLY
This will work buy is considered very poor security in 2021:
Redirect the whole window to authenticate the user (good)
Save tokens to local storage (bad) - to deal with page reloads - easily exploited by malicious code
Then post tokens between iframes (bad) - can be intercepted by malicious code that adds a listener

Is this the correct way of using REST API + OAuth on top of the normal web page?

First of all, for the lack of words, I used "normal web page" on the title. Please let me explain that:
Recently, I have seen many websites such as shopify.com making the most out of the modern browsers support for html5 push-state and Ajax. Instead of submitting forms, requesting new pages I see them doing all that via their REST APIs. It seems to me like a very neat way to do things because it's faster (less page reload), and also allow greatly allows us to re-use the API code.
In these scenarios, the users access the service via the websites as they would normally do, however their interaction with the resources are powered by the REST APIs.
As I dive more into the documents, it seems like these API requests should be stateless yet should always have a mechanism to authorize/authenticate each request so I looked into OAuth2 for that purpose (Since I will need OAuth2 anyhow, to grant accesses to 3rd parties). Now, since in this particular circumstance the user's browser will act as the client to request the resources via REST, I want to know what is the recommended flow to do it.
Right now I plan to implement it as followed: (I'm using Symfony 2 with FOSRestBundle and FOSAuthServerBundle)
User should login via the web form as normal (Since we need to authenticate/authorize both for the normal web page as well as for the API Requests)
When the user logged in, immediately check if an OAuth client is already created for this user? If not then create it with GRANT_TYPE_IMPLICIT. If the client is already there, just retrieve it.
Proceed to normal OAuth authorize for Rest requests?
Edit 1:
Further research makes me think that I should not send back the refresh token to the JS app as this would be too dangerous if the browser is compromised. Perhaps I could store the refresh token for the user somewhere in the server backend once he/she is logged in, then can reserve a special link for the JS app to request for new access token when old one expires? This seems a bit messy to me tho.

Mobile app Web API authentication

I'm building a mobile application (that might also later become a web application). The server side is a ASP.NET MVC + Web API application and I'm thinking about ways how I could implement the service's user management and authentication.
How should I implement the registration/login screen in the app? Offer native app forms, that will send just API requests to the service or is it preferable to show a web browser component and display the website's login page and then extract a token after the user logs in? I see the first option is more user friendly, but the second one will let me change the login / registration page (like for example adding external authentication providers) without breaking older versions of the app.
My second question is regarding the external authentication providers. ASP.NET Identity has good support for them and it is quite possible to let users register using Facebook or some other OAuth2 provider. Does it make sense to add support for external authentication providers when I plan to expose the app's API publicly? Are there any reasons why that is not a good idea?
Your first option is best if you believe your users will trust you to manage their passwords. You make a secure call to your service, have the service produce a bearer token as the result. That would be an anonymous call. I used the answer from this question to get me going down that path:
Get IPrincipal from OAuth Bearer Token in OWIN
If your users are less likely to trust you with their credentials, then the web view and external provider is a good alternative. You would need to work with providers that support the "Implicit Grant Flow" since don't want to share the apps clientid and client secret on the mobile device. This approach involves using a web view to login in, and then capturing the token on the client uri fragment on the response. I think it is on a location header, but don't have a working example in front of me. Something like:
https://your.domain.com/#access_token = 8473987927394723943294
you would pass that token with each api call afterwards .
Good luck!

OpenID + OAuth for Webapp and Desktop/Mobile application Authentication and Authorizaiton

I'd like to use OpenID to authenticate users on my webapp -- similar to how StackExchange does it. I'd also like to enable users of my website to use my Desktop and Mobile Apps using the same account. I've read this requires OAuth (OpenID is purely website only).
What I don't know is
Is this the correct approach?
What would the workflow for this be?
What data do I need in my database per user/OpenID? Do I store an "account" and then when they've authenticated with OpenID, I allow them to generate an OAuth Token for the mobile app?
In an ideal world, I would be able to have buttons similar to those on https://stackoverflow.com/users/login for both my WebApp and also in my Desktop and Mobile Apps which would simply allow users to login with their google or facebook account, is that possible? Simplicity for users is paramount, because my userbase will not take well anything remotely complex.
Can I use something like DotNetOpenAuth to provide all of this functionality?
Would a better solution be to break this up and allow users to authenticate to my site with OpenID and then I provide my own OAuth scheme for my desktop and mobile clients?
Probably the simplest mechanism is to embed a web view, and simply watch for navigation to a specific callback page and grab the authentication data that way. You should still be able to use OpenID for this.
What you should be looking into is Windows Identity Framework (WIF), it will work similarly for Web or Desktop applications using Claims-Based Identity. You would store an authorization token for each user (along with any other information you need) and you would get it in the Authorization Header of an authenticated HTTP Request. oAuth is the protocol for passing authorization requests and responses. WIF is a .NET toolkit to simplify this interaction.
For more info, check out the WIF home page and the following blog (not mine):
http://msdn.microsoft.com/en-us/security/aa570351
http://blogs.msdn.com/b/vbertocci/
This is the workflow that I came up with, and so far I think its working well.
The user is required to authenticate to the website via third party OpenID/Facebook/etc (mobile friendly website is available). Then, in their "profile" they can generate an API "key" which they can copy/paste into their client software. It isn't 100% transparent to the user, but its pretty good.

What are the pitfalls of embedding a form within an iframe on an external domain

Scenario:
We provide a hosted site that clients pay to use internally (a tool to support their business workflow). We have a requirement to provide a form that the clients can 'embed' in their outward facing site. This form will permit a member of the public to enter some details to register an interest - this data will be pushed to our remote system.
Question:
I'm currently planning on creating a simple HTML page that the client's web guys can include in on their site with a minimum of technical knowledge required (either using an iframe or an object tag). If I do this, am I going to run into difficulties when the user tries to submit the embedded form (as it will be going to different domain to the one they are currently browsing)?
I had a look at google adsense and I see that they just provide a link to a JS file that renders their ads - I'm not sure I see the advantage in this, but if anybody has any bright ideas...
Whatever technique that gets used, I'll have to authenticate the request as coming from my client's site(s).
If I do this, am I going to run into difficulties when the user tries to submit the embedded form (as it will be going to different domain to the one they are currently browsing)?
No issues, you'll need to hardcode a post url into your form.
Whatever technique that gets used, I'll have to authenticate the request as coming from my client's site(s).
That may be difficult. The request will be coming from the user's browser.
You could make it a requirement for a client to define some JavaScript variable in the containing page, like:
var client_id = '2315213452';
and attach a script to pick up this value and submit to your server along with the form.
The trouble is, any hacker could see this value in plain text and take it thus compromising your security.

Resources