Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I like the way that OAuth/OpenID can authenticate/identify a user from another domain, but only if the other domain allows it (presumably on the user's instructions).

I would like to do something similar, but using CORS AJAX or an alternative like JSONP. The problem is that when using a whole-page redirect, the "login domain" can be certain about which domain it's supplying the auth_token/info to, because it's issuing an HTTP Redirect itself. However, that's not true for JSONP.

My current thoughts are below, and my questions are:

  • What are the weaknesses in this pattern?
  • Is there a way of doing this without two separate requests (for the non-CORS case)?

General case:

EDIT: This section originally assumed a JSONP request - in fact, I think it could be any type of data

Case A: user logged in on the "login domain" (using cookies)

  1. The client makes a request to the "login domain", supplying a URL on the "service domain"
  2. The login server looks at the supplied URL, and thinks "yes, that's fine", and returns an HTTP Redirect (3XX) response that includes an auth_token/whatever in the URL
  3. The client follows the redirect back to the service domain. The service domain stores the auth_token/whatever in the session, and returns a static resource (e.g. an image)
  4. The client then makes a second request to the service domain (no cross-origin allowed) to retrieve the auth_token/whatever.

Case B: user not logged in on the "login domain", or has not authorised sharing details with the "service domain".

  1. The client makes a request to the "login domain", supplying a URL on the "service domain"
  2. The login server returns an HTTP Redirect (3XX) response that includes a "not authorised" status in the URL (or perhaps the URL of a full-page OAuth-style login)
  3. The client follows the redirect back to the service domain. The service domain stores the "not authorised" status in the session, returning a static resource to the client.
  4. The client then makes a second request to the service domain (no cross-origin allowed) to find out that authorisation/identification failed.

Case C: other site attempting to inspect login status

  1. The user navigates to the dodgy site
  2. The client makes a request to the login server, supplying a URL on the actual service domain
  3. The login server redirects to some page on the actual service domain, which returns a static result
  4. The user may or may not be logged in - but the client can't find out because the "service domain" endpoint that would tell them is prohibited by the cross-origin restriction

CORS AJAX case

If the "login server" endpoint has CORS enabled, then the request could be made as an AJAX request. If the "service domain" endpoint does not have CORS enabled, the final result of this AJAX request could actually be an echo of the auth_token/whatever, instead of requiring a second request.

  1. The client makes a CORS AJAX request to the "login domain", supplying a URL on the "service domain"
  2. The login server returns an HTTP Redirect (3XX) response that includes the auth_token/failure/whatever in the URL
  3. The client follows the redirect back to the service domain.
  4. The service domain returns a document containing all the info supplied in the URL (auth_token/whatever).

In fact - this "echo the auth_token" behaviour could even be used instead of the static resource from the above section, thus supporting both models with the same endpoint.

share|improve this question
    
This would also let me do JSONP/CORS requests between domains, if the other domain is authorised by the user / login server. If the other server doesn't have a required auth_token/whatever, it stores the original request data somewhere, forwards the client on to the login domain, and then waits for the redirect sequence to come back to it, at which point it can take the auth_token (or lack thereof) and process the stored request. –  cloudfeet May 31 '13 at 15:21
    
It could even work for cross-domain POST/PUT/etc. - if the "service domain" saves the data and redirects to the "login domain" with a 303 (instead of a 302), then the redirects should be continued with GET. –  cloudfeet May 31 '13 at 17:11
    
I don't see why you can't use oauth and then use the token to restrict access to the CORS interface. There is no reason to reinvent the wheel. –  Rook Jun 1 '13 at 6:50
    
The question is more how to get the OAuth token in the first place. If the user is signed in, and has already told the OAuth provider about your app, then your app can obtain an OAuth token without any actual input from the user (just forwarding the browser between sites). I was looking for a way to do that (or the similar problem of SSO) with AJAX instead. –  cloudfeet Jun 1 '13 at 16:14
2  
The oauth "state" variable is intended to be used in this way. –  Rook Jun 2 '13 at 0:22
show 8 more comments

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.