OAuth2 Flows

Apr 22, 2019 06:38 · 831 words · 4 minute read

The car continues to thunder down the highway, as its driver continue to spew on nonsense about OAuth2 and the end of the world. In the last episode you were told about the diverse roles and flows that OAuth2 comprised. You were promised more information about the flows this time around, although, speaking of time, it was only a few seconds ago for you.

OAuth2 is essentially a way for a Client to get access to resources. This almost always involve transferring secrets back and forth from the Client to the Authorization Server, the only exception being the implicit flow. You’ll therefore see this part in all flows except “implicit grant”:

Let’s go through the flows in order of complexity. We’ll start with Client Credentials first because it’s literally just a fancy Basic Auth.

Client Credentials

The one where you say who you are and get a token as a reward.

This grant is simple and is dedicated for server-to-server stuff. As a result of using this grant you shouldn’t generally be able to access a specific user’s resources (because you don’t have the permission of the Resource Owner). You should be able to access the resources you created as a client, though.

Required parameter

You must set grant_type to be client_credentials. (Because that’s how the server knows you’re trying to do Client Credentials auth.)

Sequence Diagram

… told you I’d do that.

Explanation

  1. Client makes a Basic Auth request with grant_type=client_credentials to the authorization server’s token endpoint.
  2. Authorization server spits out a response containing an access token, and can but should not include a refresh token.

I mean… that’s easy. And more secure than sending the client_id and client_secret on every request.

I’ll just move on to the Authorization Code grant type because there’s nothing to see here, carry on.

Authorization Code

This is probably the most popular form of OAuth2. It’s a bit more complicated than Client Credentials, but the “talking to the token endpoint” part is essentially the same.

With this flow, the user has the opportunity to grant or deny your client access to his resources explicitly.

Sequence Diagram

Explanation

Here it’s a bit more hairy, because there’s three parties involved. Things happen in three steps, which I guess is why this grant type is also referred to as “three-legged OAuth”.

  1. Client sends the human to the Auth server to complete authorization, providing (or having provided in the past) a redirection URI.
  2. Magic happens. The Authorization part itself is specifically out of scope. If everything is okay, the human is sent back to the redirection URI, with parameters (including an authorization code) in the query component of the URI.
  3. Client exchanges the authorization code for an access token, and potentially a refresh token. Required parameters for this are:
  • grant_type, must be equal to authorization_code
  • code, must be the value you received from the authorization server
  • client_id, which is… well… your client_id.

You also need to provide the redirect_uri if it was specified during step 1. That’s all.

Implicit Grant

Like Client Credentials, except weird. Also you don’t do an access token request, it’s given back as part of the authorization request.

Sequence Diagram

Explanation

The token is directly in the URL you’re redirected to once you complete the authorization. I realize typing this that this flow is much simpler than authorization code grant, and the next one is even simpler.

Huge Warning

This leaks the token to the user, which is a thing none of the other flows do. Be careful, here be dragons; the standard itself says that the token could potentially be up for grabs by anything on the user’s device. Probably prefer any other flow if you possibly can.

Resource Owner Password Credentials Grant

Translated: User Password Grant. This flow is the worst. The client nabs the user’s username and password and punts them over to the Authorization server. The only way this could be worse is if you stored the credentials in the client, and then used Basic Auth for every single request. At least with this you have an Access Token and a potential Refresh Token and you’re only sinning once. Hopefully.

I’m not even going to make a graph for this, essentially avoid if at all possible, which it probably is if you’re reading this blog, and if you’re reading this blog and still picking this flow, it is a failure on my part to communicate how bad this flow is. Let me repeat it in all caps, it’s been a while since I typed a whole sentence holding down the shift key, caps lock having long since been remapped to ctrl:

UNLESS YOU ABSOLUTELY KNOW WHAT YOU ARE DOING, AVOID THIS FLOW LIKE THE PLAGUE, OR A ZOMBIE OUTBREAK, OR AN ECONOMIC COLLAPSE; I WILL NOT BE RESPONSIBLE FOR ANY SMACKS BEHIND ANY HEADS THAT RESULT OF USING THIS FLOW AFTER READING THIS ARTICLE, AND I REVOKE YOUR RIGHT TO READ THIS BLOG IF YOU DO USE THIS FLOW WILLY-NILLY.