-
Notifications
You must be signed in to change notification settings - Fork 5
Security (oAuth 2.0)
Our implementation efforts based on the following documentation raise questions and therefore are incomplete.
##Documentation
We have relied on the following documentation:
- Google: https://developers.google.com/accounts/docs/OAuth2WebServer
- Facebook: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
- Twitter: https://dev.twitter.com/docs/auth/application-only-auth and https://dev.twitter.com/docs/auth/3-legged-authorization (posting messages requires 3-legged-authorization)
- Windows Live: http://msdn.microsoft.com/en-us/library/dn631818.aspx
The following examples have been scrutinized but have not proved satisfactory:
- Evgeny Aleksandrov provides the best example by far (bearer tokens, stateless api) but uses oauth2orize as identity server, instead of Facebook, Google, Twitter, Windows Live or any other public identity server.
- Brandon Werner provides an example using Windows Azure AD.
- Scotch.io easy series is a very detailed example about implementing passport-oauth2 strategies for web sites but not RESTful APIs;
- CORSnection implements the API as views and uses cookies and sessions instead of bearer tokens;
##Identity provider configuration
The configuration of oAuth 2.0 identity providers starts at:
- Google: https://console.developers.google.com/project
- Facebook: https://developers.facebook.com/apps/
- Twitter: https://apps.twitter.com/app/
- Windows Live: https://account.live.com/developers/applications
Check https://github.com/jlchereau/Phonegap.Express/issues/16.
Update https://github.com/jlchereau/Phonegap.Express/blob/master/config/development.json accordingly.
Note: In your development environment, create a redirection in %systemroot%\system32\drivers\etc\hosts
(windows) in order to mock a public domain especially for Windows Live
##oAuth Authentication Flow
The oAuth 2.0 authentication flow is represented here.
We could not really figure out how to plug passport-oauth2 and other derived authentication strategies (passport-facebook, passport-google-oauth, passport-windowslive) to handle the authentication flow above. Apparently, when you use passport-oauth2, you do not use passport-http-bearer and vice-versa, but the passport documentation is minimal and we might have misinterpreted it.
Our implementation follows the following steps (with links to code lines):
-
The user clicks a login button (Facebook, Google, Twitter, Windows Live, ...);
-
The click triggers a call to
http(s)://<apiserver>/auth/{{provider}}/signin?returnURL={{returnURL}}
which:- saves the provider, ip address and returnURL,
- returns the url of the provider's login dialog with options set;
-
The browser (or Phonegap application) opens the provider's login dialog at this url and the user approves our application;
-
The identity provider redirects the browser to the callback url registered with it, in our case
http(s)://<apiserver>/auth/{{provider}}/callback
, sending an authorization code; -
After some security checks The API Server sends the authorization code to the identity provider to obtain an authentication token
-
Upon reception of the authentication token, the API server requests and saves a user profile;
-
The browser (or Phonegap application) is then redirected to the returnURL above with a hash containing the authentication token;
-
The browser (or Phonegap application) parses the token which is saved in localStorage.
The oAuth 1.0a flow (Twitter) has not yet been implemented.
##Authorized API Calls
The security of our RESTful JSON API relies on passport-http-bearer.
CRITICAL: We want a RESTful API. RESTful = stateless. stateless = no session (& cookieless).
Note: the session object created and saved in database in the flow above is not a stateful session maintained on the server during the entire user session.
Authorised API calls:
- read the token from localStorage;
- are sent with the required Authorization headers;
- On the API Server, the token received is checked by the passport bearer strategy.
##Questions
- Are there reasons to maintain a username + password in addition to oAuth 2.0 authentication like most sites (except identity providers' sites) do? At this stage, we have assumed that we could rely entirely on external identity providers.
- The code at https://github.com/jlchereau/Phonegap.Express/blob/master/api/routes/authentication.js might reinvent the wheel considering passport-oauth2 and derived modules including passport-facebook, passport-google-oauth and passport-windowslive but we could not really figure out how to use them alongside passport-http-bearer.
- Do we need refreshing tokens noting that Google and Windows Live tokens expire after 1 hour (3600 seconds) but can be refreshed and Facebook tokens have a much longer life span but cannot be refreshed?
- How is logout/signout different from revoking tokens and how should this be implemented?
- Should we keep track (User Mongoose Schema) of several active tokens per user to account for signing in from different devices (phones, tablets, PC browsers) with different identity provider accounts (Facebook, Google, Twitter, Windows Live, ...) and to be able to post messages on their behalf while they are offline?
The TODO list is maintained as a list of issues.
Copyright © 2013-2014 Memba Sarl. All rights reserved.