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)
- The client makes a request to the "login domain", supplying a URL on the "service domain"
- 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
- 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)
- 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".
- The client makes a request to the "login domain", supplying a URL on the "service domain"
- 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)
- 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.
- 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
- The user navigates to the dodgy site
- The client makes a request to the login server, supplying a URL on the actual service domain
- The login server redirects to some page on the actual service domain, which returns a static result
- 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.
- The client makes a CORS AJAX request to the "login domain", supplying a URL on the "service domain"
- The login server returns an HTTP Redirect (3XX) response that includes the auth_token/failure/whatever in the URL
- The client follows the redirect back to the service domain.
- 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.
303
(instead of a302
), then the redirects should be continued with GET.