4

I am trying to understand how to add social login and registration to a service. After reading many blogs posts, many reminding me of the pitfalls of designing such a system, of the fact that Oauth is for Authorization not Authentication, most written by people exploring this topic as they write, all with different opinions on what OpenID/OpenID connect/etc is all about, I am finding myself more confused than before I started.

My understanding is that with Social Login the ID-provider does the Authentication. When the user is authenticated, the client (or the user agent) must be in possession of something (a secure token?) that indicates that the user managed to prove their identity. On subsequent requests to /the/ API, the server, which from the point of view of the ID provider is a 3rd party (called a relying party in some documents?) would need to be able to verify this "token" and needs to be able to derive from this "token" who the actual user is.

So, in practical terms:

  • What would the API receive from the client when a user signed in using with Social Login?
  • What would the API receive from the client when a user registers with Social Login?
  • As a minimum what do I need to store about each user for authentication purpose (User-ID? Email for recovery/linking multiple accounts? ID-provider (in what format?), List of current sessions/expiry dates? Last access/update time maybe? What else?)

The current system (a REST-full API) issues a token when the user signs in with email/password with a post to api.example.com/session. In this case the API is able to check that the user supplied the correct credentials.

I gather that many articles online talk only about how to use the tokens to consume the resources provided by that same organisation, eg Facebook login for consuming Facebook APIs. This might just be my misunderstanding though.

Some specific questions:

  • What does this token look like? Does it reveal the Identity Provider or how to verify the validity of the Token?
  • Does the token give the relying party (The API backend servers) a way to obtain, say for example the user's Full Name or Email Address? Or would that be functionality delegated to the Client?
  • Who determines what information this Token provides - The ID provider or the client application?
  • What about the case of a Web client where the client and user-agent is not running on the same device? Can the client or user agent "build" a new token which can be used to sign requests to the API, and include the important details (User-ID, ID-provider, expiry date, client-ID)?
  • Can the API "session" endpoint be extended to handle "social login" tokens or is that not the correct approach?
  • Is it important to Identify / Authenticate the Client? If so how - I believe mobile clients cannot securely store a signing key!?

A note about oAuth and Authorization: I don't think I need authorisation here. The API already determines whether requests are authorised based on the identified user.

  • 1
    I feel like the lion share of these questions would be answered by writing a hello world for oauth, or implementing a facebook/google/twitter oauth quick-start guide. Honestly, you'll understand the protocol better if you use it. – rook Oct 10 '16 at 15:48
  • @rook I have started to look at it, but I am very aware that figuring these things out by trial and error could be potentially fatal... – Johan Oct 10 '16 at 17:57
  • and bad advice can also kill. You could distill this massive post into one or two important talking points if you actually used the technology. – rook Oct 10 '16 at 17:58
  • @rook You're not helping me. How would you break it up? – Johan Oct 10 '16 at 18:29
  • @Johan there's a difference between using trial and error and then assume you've learned everything, and using trial and error to distill basic function. Your questions of "what would this look like" would be answered if you fired up a test environment. – schroeder Oct 12 '16 at 21:22
3

I would suggest that you start with some of Dominick Baier's courses on Pluralsight. In particular, you might want to start with his Introduction to OAuth2, OpenID Connect, and JSON Web Tokens (JWT).

If you are writing services that require the user to login every time to use, then I don't think you want to use OAuth. If you are writing some kind of mobile or service app which needs to later login to these services on the user's behalf, then yes, you should consider OAuth. As Dominick Baier explains, the OAuth spec is a bit of a mess, and OpenID Connect is even more so.

I would suggest you do the following:

  1. Use a "Federated Secure Token Service (STS)". The purpose of the Federated STS is to issue your application with authentication tokens which contain "claims" that your application understands. For example, these claims could contain the user's email address, full name, etc. -- whatever you specify. When the user tries to access your services, they are re-directed to this "Federated STS" which offers the user choices at to how they want to login (Facebook, Google, Live, LinkedIn, etc.). The user then logs in, the Federated STS receives the authentication token from Facebook or LinkedIn or whatever, transforms the token and its claims into a format your app understands, and your app then consumes this nicely made authentication token. There are a number of Federated STS services, including Azure ACS, Azure Active Directory, etc.
  2. You probably want the token to be a JSON Web Token (JWT). In the configuration of the Federated Identity Provider, you specify how you want it to "transform" claims into a format your application can understand. For example, if you application wants a "Full Name" field, and Facebook returns a "First Name" and "Last Name" field, you can instruct the Federated STS to convert the Facebook information into a "Full Name" field. Here is an example of what a JWT looks like:

    { "sub": "1234567890", "name": "John Doe", "admin": true } but you can choose to have whatever fields you want.

  3. After the client logs in, is authenticated, and redirected back to your API, the API will typically receive an HTTP header with the JWT token, although there are other schemes.

  4. You can configure the Federated STS so that it will also return the name of the Identity Provider the user chose (Facebook, LinkedIn, etc.)

  5. I don't completely understand your question about the "client and user-agent" not running, but you might want to look at OAuth2 and "refresh tokens" for this.

  6. Yes, it is very important to authenticate the client.

  7. Rather than extend the API to handle different kinds of authentication schemes and tokens, I think you should use the scheme I advocate above to offload all the authentication to a "Federated Identity Provider/STS" so that your code is not tightly coupled to authentication, and so that you can add new "Identity Providers" and "claims transformations" to the Federated STS in the future without any code changes.

  • The second paragraph is very good (+1). Authentication != authorization, and OAuth is just authorization. – grochmal Oct 12 '16 at 23:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.