RESTful Webservice – How to Architect for 3rd Party Authentication

authenticationoauthopenidrestweb services

For my job we have a nice RESTful webservice we've built out that we use to drive a couple websites we have. Basically the webservice lets you create and work with support tickets, and the website is responsible for the front end. Any webservice requests use an auth header which we use to validate the user and their password for each call.

This year we're looking to expand our login options so that users on the website can log in via Google, Twitter, and Facebook (possibly others). However I'm having a lot of trouble figure out how to architect this so the webservice can use the 3rd party authentication providers to ensure the users is who they say they are. Is there any best practices out there for how to do this?

Currently we're thinking of having the website handle authenticating the users themselves, and then use a new setSessionId call that registers their current session with the webservice back end. Each additional request to the webservice will pass along that sessionId and will validate it. These seems okay, but I have that feeling in the back of my head that I'm not thinking this through and all my forum browsing and reading oauth and openid specs is just confusing me more. Any tips for how to tackle this?

Best Answer

It sounds like there are two goals:

  1. Easy for end-users to authenticate with their existing social accounts
  2. Easy for developers using your webservice

Authorizing people to use resources on your site makes OAuth2 a preferred mechanism due to the popularity and availability of client libraries.

1. Easy for end-users to authenticate with their existing social accounts

The end-user visits a site that uses your API and chooses to login. They are sent to your OAuth login page. Your login page shows a normal username and password prompt for accounts managed on your site and a set of social auth buttons where they can click to login via a site like Facebook. When the user chooses Facebook you redirect them to Facebook to approve the choice (starting the facebook auth flow). When the end-user completes the login at Facebook they are redirected back to your site.

When the user is redirected back to your site from Facebook you save that user's information into a user record in your database and then generate a new session for that user. You immediately redirect the end-user to their original downstream site with the oauth access_token, completing the original oauth flow.

2. Easy for developers using your webservice

If you are the provider of authorization then you should create a simple interface for developers to depend upon which does not change every time you add a new upstream auth provider which doesn't implement oauth perfectly. This is why I believe you should implement an OAuth2 provider site and that site should be a consumer of the social auth sites.

To the developer using your nice rest API, they will not be aware of the Facebook interaction unless you choose to give them a hint through the session capture post (for example).

TL;DR

Make consumers of your APIs like you by implementing OAuth2 and hiding social auth complexities. You can, during your oauth flow for your downstream sites, trigger an additional oauth flow with facebook.

Image because picture == words * 1000:

enter image description here

Can we call this oauth2-piggy-back?

Step by step flow

  1. End user visits site that uses your API
  2. End user is sent to your site to authorize or signup (oauth2)
  3. End user picks social auth, clicks facebook login button
  4. Your site sets a cookie or sets the state in the facebook oauth to know where the user came from
  5. End user redirected to Facebook and accepts connection at facebook site
  6. End user redirected to your site to complete facebook auth process
  7. You lookup or create the user in your database
  8. You create a new session on your server
  9. You redirect the user back to their original site with your session token
Related Topic