An OAuth 2.0 introduction for beginners

How OAuth 2.0 works and how to choose the right flow

Lorenzo Spyna
ITNEXT

--

TL;DR;

You suck! You just want the code.

However, at the end of the article, you will find a questionnaire to help you choose the flow you need.

This article doesn’t want to be the final guide to OAuth 2, but an introduction to the flows that this framework is composed of. You’ll have a look at the four basic flows and some practical scenarios, to understand the involved actors and the detailed behaviors. The goal is to be able to choose a flow that best fits your needs.

Which Oauth 2 flow should you choose?

To make it as easy as possible, the experts will forgive me, we can say that there are four different versions. Or, more correctly, four different flows. OAuth 2 is the totality of these flows. It’s not mandatory to implement them all, but only the ones that you need.

The goal remains always the same: to obtain an access_token and use it to access protected resources. The four modalities are:

  • Authorization Code Grant: A code is issued and used to obtain the access_token. This code is released to a front-end application (on the browser) after the user logs in. The access_token instead, is issued Server side, authenticating the client with its password and the obtained code.
  • Implicit Grant: after the user logs in, the access_token is issued immediately.
  • Client Credential Grant: the ’access_token is issued on the server, authenticating only the client, not the user.
  • Password Grant: the access_token is issued immediately with a single request containing all login information: username, user password, client id, and client secret. It could look easier to implement, but it has some complications.
Requirements for OAuth 2 flows

Authorization Code Grant

The authorization code flow, as detailed below

This is the most complete and complex flow. The login process is divided into two phases, which ensure greater security.

The involved actors

  • User: the person who wants to be authenticated, to access protected information.
  • Client App: In this flow, the client is usually a web application. The application must have both a front-end and a back-end, later we’ll see why. This means a pure Front-end application (Javascript, React, Angular) cannot implement this flow but can use the Implicit grant one.
  • Authorization Server: is the component that performs the authentication and the authorization, it handles login requests, user authentication, token generation, and security validations.
  • Resource Server: it exposes resources, as they could be REST API. After the Client App obtains the access_token, it will use it to call the Resource Server. One of the differences between the Authorization Server and the Resource Server is that the first one “only” handles authentication and authorization, and the second one “only” serves the content (the resources). This division can generate some confusion: it’s important to remember this is a logic difference and not an implementation rule.

The flow

Let’s see in detail the Authorization code grant flow.

1. The user wants to log in

The classic scenario for this flow is played in the user browser. The user will click the “Login with OAuth” button and the client will generate and send a login request to the Authorization Server.

2. The user is redirected to the Authorization Server

The client generates a login request for the Authorization Server. The request will be sent in the form of an HTTP Redirect and the information will be sent as GET parameters.

GET /tokenLocation: https://the-authorization-server/token?client_id=[the_client_id]&redirect_uri=[a redirect uri]&response_type=code&scope=[list of scopes]&state=[some client parameter]

The parameters are the following:

  • client_id: to identify the calling application
  • redirect_uri: the URL to which the Authorization Server will send (through a redirect) the Authorization code, after the user login.
  • response_type: identifies the type of response the Authorization Server will return. The value code is the one usually in the Authorization code flow.
  • scope: a list of permits the application asks the user. For example: read_email, write_post. The user will be asked to grant those permits. This will be useful when the client will access the Resource Server. This one will decide if permit o deny the access. For example, a client, logging in with Facebook, ask the email scope. If the client (once obtained the token) calls the /{user-id}/friendlists API, that needs the friend_list scope, will obtain an access denied error.
  • state: this optional parameter will be returned as-is to the client, after the login process. It can be used to retrieve information on the client’s application about, for example, to the user session.

3. Request validation

L’Authorization Server must validate all the request parameters:

  • client_id: Does a client exist with this id? Is the client allowed to perform this request?
  • redirect_uri: Can the client use this redirect URI? Is this redirect URI associated with this client?
  • response_type: Is the client allowed to use this response type?
  • scope: Is the client allowed to use these grants?

To execute these validations the Authorization server must have previously registered all the clients that will access. The onboarding and the maintenance of clients are out of the OAuth scope.

4. Login form

The Authorization server shows the login form, and the user has to insert the username and password, to make the login (step 5 in the picture).

After validating the data (step 6 in the picture) the Authorization server asks the user the consents specified in the scopes. The user will decide to grant, or not, one or more of the scopes. On the contrary case, the client will act differently. For example, it could limit or inhibit the use of the application.

7. Redirect to the client with the authorization_code

The Authorization Server generates an authorization code (authorization_code) and sends it to the client, to the URI specified in the request.

All these operations have happened client-side, on a browser (or a mobile app) for the next steps the client must use a back-end.

This, in my opinion, is one of the aspects to consider when you choose which OAuth 2 flow best fits your needs.

8 and 9. Authorization code validation

Now the client has to call the Authorization Server to validate the received code. To do this operation it will pass:

  • the authorization_code to be validated.
  • the client_id: this is needed, along with the client_secret, to be sure the request comes from that client, and the token is not “stolen” when you were on the front-end.
  • the client_secret is the client password, and it must be stored in a safe place, this is why you need a back-end.

The Authorization Server executes all the above validations, checking the authorization_code is intact, not altered, not expired and issued for that specific client.

10. The client receives the access_token

The Authorization server creates an access_token and returns it to the client. There are many types of token, they have an expiration date and they can be refreshed. Usually, along with the token, are returned some more information:

  • the token_type: one of the most famous is Bearer, which means: grant access to the bearer of this token. mac is another type.
  • expires_in: the duration of the token
  • refresh_token: another token, to renew the access_token when it expires.

11. The client uses the access_token.

Now that the client has obtained the access_token, it can use it to authenticate itself against the Resource Server.

The Resource Server is a generic component and could serve many different types of resources: REST API, SOAP Services, Web pages, etc… Based on the resource type, the method to send the access_token can change. The most common way to send it against REST API is to use the HTTP header: Authorization, concatenating the token_type with access_token. Example:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ

12 and 13. Token validation

When the Resource Server receives a request must check the token presence and integrity.

The token validation, especially based on its type, can be done in many ways. In some cases the Resource Server can validate it, in some other must call the Authorization server.

In some scenarios is possible that these two components are the same application, this is transparent and not important for the client. If you need to implement an OAuth server the choice on how to validate the token will vary based on your architecture and on the token type you’ll decide to use.

14 and 15. Access and display protected resources.

Once the Resource server validates the token successfully, it will return the resource to the client, and this can display it to the user.

Implicit Grant Flow

This image shows the OAuth 2.0 Implicit grant flow

This flow is very similar to the Authentication Code one, but the access_token is immediately returned to the client after the user login, in an implicit way. You use this flow in Single Page Applications and pure Javascript applications, where is not possible to keep the client_secret secret. The actors involved are the same as the previous flow.

The first difference is that during the initial redirect to the Authorization Server, the value of the parameter response_type is token instead of code. This means the type of response from the server will be (immediately) an access_token, instead of an authorization_code.

In this way, you’ll have one step fewer to execute for the client, but also less secure, because the whole flow is executed on the browser (or user-agent generally speaking), including the token. In the authorization code flow, the token comes from a server to server call, so it is more difficult to intercept or manipulate it.

Client Credential

Client Credentials grant flow

The main difference between the flows mentioned above is that in this one there is no user interaction. The application executes the authentication request directly.

This means the application cannot do any action on behalf of the user, but just on behalf of itself.

This flow doesn’t take place on the browser but on a server. There are not redirect, but an HTTP POST call is executed, the parameters of the requests are:

  • client_id
  • client_secret
  • grant_type: client_credentials
POST /token&client_id=my-fancy-client-application
&client_secret=xxxxxxx
&grant_type=client_credentials

The response of this request is the access_token, that can be spent on the Resource Server.

Password Grant flow

Password grant flow

The main concept, in my opinion, of this flow, is the users enter their username and password in the client application and not in the Authorization Server. A noticeable thing is the credentials “belong” to the Authorization Server, not to the client,

This fact implies that the users must fully trust the client application, to insert their Authorization Server credentials. To better understand this, imagine you make an application that logs in users with Facebook, but the users insert their (Facebook) username and password on that application. Would you, as a user, do this?

You must be sure the application is absolutely trusted and, for example, does not save or modify your Facebook password.

if I remember correctly, Spotify has this feature, probably using this OAuth 2 flow. I remember I did a login using Facebook credentials directly on Spotify.

Once the username and the user password are collected on the front-end, they are sent to the application back-end, that executes an HTTP POST to the Authorization Server. The parameters of this request are:

  • grant_type: password
  • username of the user
  • password of the user
  • client_id
  • client_secret
POST /tokengrant_type=password
&username=username@authorization-server.com
&password=TheUserPassword
&client_id=my-fancy-client-app
&client_secret=xxxxxxx

The Authorization server, after validating all the credentials returns the l’access_token.

For this flow, you need both a front-end and a back-end.

Implementation of OAuth 2

Photo by Fancycrave on Unsplash

To implement OAuth 2 you have to develop:

  • The client: if you want to use an Authorization Server services
  • The server: if you want to expose authentication mechanisms

Client-side

You must remember, again, that to implement some of the OAuth flows you need to use the client password, and this must be kept in a secure place. So you may need a server.

This means you cannot implement some flows if you don’t have a server. The applications that don’t need a server ( to be served) are Single Page Application and the application that runs on a user device: Mobile and Desktop app. You can bypass this problem by creating a dedicated server or back-end to do the OAuth server calls, or by using some crypt mechanisms.

Server-side

There are many frameworks in many languages that implement OAuth. This makes life a little easier, for the part of exposing the needed endpoints; and especially for all the validations that are needed. But rarely I found “turnkey” solutions.

One hard thing to do is the onboarding and the management platform for the clients. Just think about the many existing developers.[preferred-social-network].com to understand they are complex applications.

You also have to pay attention to the scopes and permissions, whose management is everything but banal, especially in the resource protection phase.

Another point of interest is the token management. Use of a database is required, to guarantee the complete lifecycle:

  • release
  • renewal
  • expiration
  • revocation

Which flow should I choose?

Answer these questions, and you will find out which best fits to you.

The choice of the right flow depends on many factors, answer these questions to have an idea of which best fits you.

Are you able to maintain the client_secret in a safe and secret place?

  • Yes: next question
  • No: IMPLICIT GRANT

Is your application a Web one?

  • Yes: Answer next question
  • No: CLIENT CREDENTIAL GRANT

Do your users trust you enough to insert their credentials (username and password) on your site? For example: Would users insert their Facebook password on your site?

  • Yes: PASSWORD GRANT
  • No: AUTHORIZATION CODE GRANT

Conclusion

I hope the world of OAuth is more clear now that you read this article, my goal was to explore the basics of this protocol. If you have any comments or proposition you are welcome to leave them down here.

Congratulations!! 😎 You made it to the end. And if you liked 👌this article, hit that clap button below 👏. It means a lot to me and it helps other people see the story.

More posts by spyna.

--

--