I have some confusions on OAuth-related topics and I hope someone can help me clear them up :) Feel free to correct me on any point where I'm off the mark.
So let's say that my web company runs a number of websites on different domains:
Let's say that these are e-commerce sites with some social thrown in, so there's user accounts with various stored data points. So my company (let's call it ACME E-Commerce) has created and is administering all of these sites for different customers.
Now, we decide that it would be convenient to have one central account for all of our e-commerce websites; the benefits include reducing friction by allowing customers to use their existing account to log into any of the sites, as well as centralizing information to improve marketing accuracy and reduce excess communication with the customers. Enter OAuth!
As I understand from some reading, OAuth is an authentication and authorization standard. Authentication being "login" and authorization being "you can make these API calls", in a nutshell, correct? Let's start with authentication:
AUTHENTICATION!
The idea here is that you go onto socks.com and when you would normally log in there's a "Login With ACME ID" button, as well as "Login To Socks.com". You see this everywhere: Login With Facebook, Login With Google, etc. So we have "Login With ACME ID".
When the user clicks "Login With ACME ID", socks.com requests and receives an unauthorized request token directly from ACME's OAuth server, then redirects the user's browser to ACME's OAuth site. There, the user plugs in the username and password for his ACME ID account, and ACME OAuth authorizes the request token and returns it to socks.com via a redirect URL.
So at this point, Socks.com knows that the user is logged into ACME ID. If Socks.com wanted to query information from ACME's Resource API, it would exchange its authorized request token for an access token and then make calls, but we're just talking authentication, and the user has authenticated. Right?
Assuming that I have that right, and even if I have it slightly wrong, what does Socks.com do at this point? Since, in this scenario, it has its own database of users, does it synchronize that central OAuth authentication with its own database? Socks.com knows now that [email protected] is logged in, and it queries its database for that email address to get his purchase history and last cart contents? It maintains a session for joe, and if that session expires then he must again authenticate with his ACME ID?
I know that Spotify does something like this; they have "Sign In With Facebook". If I take this option, a little browser window pops up on the Facebook domain with a login window. I log in, the popup closes and Spotify shows me as logged in...with my Facebook email address, and an account name consisting of 8 or so random numbers. This seems like Spotify is seeing that I authenticated with Facebook's OAuth server, and then generating a new account for me in their own system. Subsequent Facebook-OAuth authentications/logins would throw me into the same Spotify account each time.
What, if anything, do I have wrong here?
So, with a central authentication setup with ACME ID, we can allow users to log in to socks.com, boats.com and cakes.com with the same ID, and we will courteously create accounts for them at each location. This is the friction reduction in action, but addresses and credit card data are still stored separately, so we don't get the benefits of having that centralized. However, this goes beyond authentication, we're into authorization!
AUTHORIZATION!
So we do a bit of account data restructuring and move all customers' address and credit card data into their central ACME ID accounts. We establish an API for requesting and modifying this information. Now when cakes.com authenticates with ACME ID and gets its authorized request token, that token is exchanged to the ACME OAuth server for an access token to the API. (This is stored server-side, in the user's session data or something.)
Now when the user goes to checkout on cakes.com, we can make an API call to the ACME Resources server, passing in the ACME ID username, to retrieve an array of the customer's addresses, and then use that to populate a webpage. Hey, that's good service! Cakes.com is authorized by the OAuth procedure to do this kind of thing.
Do I have everything right there?
EDGE CASES!
The above implementation of e-commerce sites with a central OAuth server is pretty clear-cut, but there are some "edge cases" where things might be implemented different ways:
1) No Distributed User Accounts
What if I wanted to force all users of socks.com, boats.com, and cakes.com to only login with an ACME ID? Perhaps it would be that there is a "user account" at each of those sites, with purchase data and address data and so on, with an associated username, but no password and no actual login mechanism. The session is marked as "logged in" once the ACME ID is authenticated.
Or, perhaps all information such as purchase history, addresses and CC #s are aggregated into the ACME Resource endpoint, and no information is stored about the customer on the satellite e-commerce sites? Well, then the satellites are basically slaves, using the ACME OAuth as a remote database. Then, because purchase history is centralized, you more or less need to centralize your items, and then perhaps it would get down to "what isn't centralized?" and "why have separate websites" -- except they need to be separate.
So, any merit to this?
2) UI-Less Web API for Mobile App
Let's say you're building an iOS/Android/etc. app called Horses, and you need to store some information in the cloud about your users, specifically what horses they really like. Despite the opinion that anyone could have about horses being disrelated to socks, boats, and cakes, you want to allow your users to login with their ACME ID as well as a Horses ID that you invent.
Now, you are basically taking the route of having a satellite user account system on a www.horses.com domain, and optionally allowing the person to login with ACME ID and graciously creating a horses.com account for them to store their horses.com-related data. Pretty standard; the one difference is that you don't actually need to build a website, it's just an API.
But, what if you wanted to only allow ACME ID as login, no horses.com account? So when you go to Login, your horses.com API would initiate the OAuth dance with ACME OAuth, authenticate, and then deliver an access token (for horses.com) to the app. That access token would be used to make read and write API calls to horses.com based on what horses your user likes in the app. Am I in the right vein here?
3) Central Auth to Access Multiple Sites
Let's take this setup: ACME ID holds username, password, email, credit card & billing information. Socks.com, boats.com and cakes.com have purchase history, as well as social information about what sock-related, boat-related, or cake-related (respectively) things the person has done on those sites.
Now we want to make a mobile app that authenticates with ACME ID, and can pull information from ACME ID's Resource API (for CC & billing data) as well as each of the sites that authenticate with ACME ID anyway. This way we can make a great fusion of socks, boats and cakes, and then we can bill the customer for it! (You get the idea.)
So...how could this be possible?
Thanks for reading!
In a centralized authorization system, you have a dedicated (micro-)service that makes all the authorization decisions (shown as Styra below). Any other service that needs an authorization decision makes a network request asking for a decision and then enforces that decision appropriately.
Authentication is a process by which one principal verifies the identity of other principal. In one-way authentication, only one principal verifies the identity of the other principal. In mutual authentication, both communicating principals verify each other's identity.
You can use identity and access management (IAM) solutions to set up a user database and define permissions for your user-facing microservices. Microservices can redirect users to the IAM system for authentication, receive an encrypted SSO token, and then use it to log in users on subsequent attempts.
OAuth 2.0 is a specification for authorization, but NOT for authentication. RFC 6749, 3.1. Authorization Endpoint explicitly says as follows:
The authorization endpoint is used to interact with the resource owner and obtain an authorization grant. The authorization server MUST first verify the identity of the resource owner. The way in which the authorization server authenticates the resource owner (e.g., username and password login, session cookies) is beyond the scope of this specification.
Authentication deals information about "who one is". Authorization deals information about "who grants what permissions to whom". Authorization flow contains authentication as its first step. It is the reason people are often confused.
There are many libraries and services that use OAuth 2.0 for authentication. It makes people much more confused. If you see "OAuth authentication" (not "OAuth authorization"), it is a solution using OAuth for authentication.
An ideal OAuth server implementation clearly separates authorization from authentication. Such an implementation requires just a unique identifier of end-user to issue an access token but does not require (handle) ID and password at all. Such an implementation does not care about how unique identifiers are determined. In other words, it does not care about how end-users are authenticated. It requires just a unique identifier that is determined as a result of end-user authentication.
It is difficult to design and implement such an ideal OAuth server, but it is doable and there exists at least one commercial implementation.
If your OAuth server does not care about how end-users are authenticated at all (= if your OAuth server clearly separates authorization from authentication), you can design your entire system more flexibly and probably you can do what you want to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With