Ben Aston
Ben Aston

Reputation: 55739

Bypassing the Same Origin Policy for authenticated XmlHttpRequests

I have a website on foo.com serving PageA.

PageA has some JQuery within it that requests via XmlHttpRequest some JSON data from a CouchDb instance residing at bar.com.

As I understand it the same origin policy prevents this, but the use of JSONP should circumvent this limitation (CORS will eventually cover this use-case, I believe.)

The server behind foo.com has a trusted connection to the database at bar.com.

Is it possible to have a user authenticate with foo.com using their OAuth credentials (Twitter login, for example), and subsequently be authenticated to use bar.com? (I presume not due to the authentication cookie only being readable by foo.com.)

Given this, is there any way I can authenticate a user to use the CouchDB at bar.com from foo.com using any of the available authentication mechanisms for CouchDB (OAuth, cookie and Basic)?

Edit: could I, for example, return user credentials for bar.com from foo.com (retrieved via its trusted link) which are then set client-side in the XmlHttpRequest HTTP header for basic authentication with bar.com. All done over TLS of course (...or is this a security nightmare?)

Upvotes: 4

Views: 851

Answers (4)

Yahia
Yahia

Reputation: 70369

From my POV even JSONP is a security risk - so I just wouldn't go down that path...

To achieve what you are asking for I see two options (both can be made to work with SSL if need be!):

  • write a custom webservice/REST/SOAP/whatever which runs on foo.com and interacts on your behalf with bar.com for authenticated clients

  • use a "generic http proxy" which runs on foo.com and maps bar.com in a way that your app/page works as if the CouchDB is running on bar.com for authenticated clients

Upvotes: 3

nothize
nothize

Reputation: 108

As I understand you wish to use JSONP from foo.com to make requests on bar.com while want bar.com to be able to know if this request is already authenticated by foo.com or not.

This is like logging in on foo.com and allowing the authenticity to be transferred to bar.com.

Assuming that the XMLHttpRequest could remember the session id in the cookie of the rest requests, how about using a One-Time Password (in fact a random string, we may call it a token) that made a call to bar.com from the page generated by foo.com after logged in depicted as below:

login request -> foo.com -> XHR(bar.com, OTP) -> bar.com
cookie updated with an active session id <- bar.com
XHR(bar.com, CounchDB) -> bar.com successfully

So if foo.com and bar.com can communicate privately(and securely!), foo.com can generate a OTP and pass this to bar.com so that bar.com knows that only the valid user can know it and therefore can treat the session id as authenticated.

Alternative courses:

  1. If the cookie used by XMLHttpRequest to bar.com doesn't persist across requests, the same OTP has to be transferred in each requests.
  2. bar.com has to provide a service to monitor for authentication authorization from foo.com for newly added OTP. It should have some time out mechanism to invalidate old tokens.
  3. bar.com may also need to provide an authentication removal service as well to prevent the risks when using public machines.

Upvotes: 0

Teddy
Teddy

Reputation: 18572

I had the same issue regarding same origin policy in xhr. I had a website and I wanted to populate autocomplete content with JSON data from a different server running CouchDB.

There are 2 ways:

  1. JSONP - this works just fine
  2. proxy CouchDB through main web server - this works great from point of view of client b/c everything is on the same host. It also makes SSL doable.

As far as sharing a login session from CouchDB and another app server, I don't know how to do that without resorting to basic HTTP authentication, which isn't really that secure. It is probably better to let app server act as middle-man b/t client and CouchDB.

Another benefit of an app server middle-man is that a single CouchDB database can have documents for multiple users. By contrast, if the client accesses CouchDB directly, you probably need to create a separate database for each user via filtered replication so that one user cannot view another user's documents.

Upvotes: 2

user1046334
user1046334

Reputation:

You can inspire from facebook authentication server-flow, substituting client for your client, server for foo.com and facebook for bar.com. Look at http://developers.facebook.com/docs/authentication. That way client should have been authenticated to use data from bar.com (in script loaded from bar.com, of course, but you can pass data to callback from foo.com, unless I am mistaken).

Upvotes: 0

Related Questions