I decided to write this article because when I started studying and learning OAuth2 I couldn’t really find any source that would help me to understand the full picture presenting also some real world examples.
The only real source of information for the OAuth Authorization framework was (and is) the original RFC6749, but it’s a bit too much especially if you are looking for an overview about what is OAuth2 and you don't want to focus on the technical details.
Scope of this article
Right. Then what is the scope of this article? The scope of this article is to provide an introduction and an overview about the authentication protocol OAuth2. It is mainly addressed to people that have “some clue” about what is OAuth2, want to understand more about the various authorization flows, but don’t want to go into the details of what field is needed in which HTTP request. For this reason I’m intentionally NOT using, in this article, any technical word like “access_token”, “clientId”, “ClientSecret” and so on. For all the technical details related to how to implement these authentication flows, the RFC6749 offers a complete reference and if you are a sw dev looking for detailed description of any single field to use in any request, that's NOT the article for you.
Why do we need Open Authentication Framework?
Yes, this was my first question once I started looking into it.
What problem I have that can be solved with OAuth2?
If we look at the RFC6749, the first line says the following:
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf.
It's a bit obscure, with all these abstract words....it didn't really tell me much the first time I read it. Let's see if we can move away from the academic formal statements and make it simpler (and yet a bit less precise).
So, in this definition, if you are developing an application, your application is the third-party application. And all these juicy social networks (but not only) like Facebook, LinkedIn, Twitter, are the HTTP Services that you want to access , in behalf of the end-user that is using your application and that in this abstract definition is called resource owner.
Now, finally, thanks to OAuth2, your application / website can use an elegant, safe approach to access some data normally owned / produced by the end-users (again, like facebook friends, linkedin posts, tweets) without need of knowing their passwords. You can even use Facebook or Google to provide you a proper user authentication management, save yourself a lot of development work and don't write hundred time the same authentication code!
OAuth2 Authorization Flows
The OAuth2 framework provides four different types of authorization flows. Based on the product that you are creating (a website, a mobile app, a standalone software) and the type of scenario you want to cover, you will have to choose one workflow rather than an another. For this reason you need to understand the difference between the various flows. My intent here is to explain you the differences using directly some examples. Let’s see if I can succeed in this….
We start from Authorization Code definition in the RFC6749. If you are curious about the formal definition, it looks like this:
1.3.1. Authorization Code
The authorization code is obtained by using an authorization server
as an intermediary between the client and resource owner. Instead of
requesting authorization directly from the resource owner, the client
directs the resource owner to an authorization server (via its
user-agent as defined in [RFC2616]), which in turn directs the
resource owner back to the client with the authorization code.
Before directing the resource owner back to the client with the
authorization code, the authorization server authenticates the
resource owner and obtains authorization. Because the resource owner
only authenticates with the authorization server, the resource
owner's credentials are never shared with the client.
The authorization code provides a few important security benefits,
such as the ability to authenticate the client, as well as the
transmission of the access token directly to the client without
passing it through the resource owner's user-agent and potentially
exposing it to others, including the resource owner.
Now, what all these words means? Let's try to make some examples.....
You have a website and you want to offer a feature for your registered users: they can post some tweets directly from your website, for instance tweeting their status, or some goals they achieve using your application.
To make this possible, any user should give you access to his Twitter username and password if he wants to allow you to tweet using his account. But the user doesn’t want to share his personal Twitter credentials with a website that he might not trust. Not considering that if he changes his Twitter password the feature will stop working....
This is a typical case where you can use the Authorization code grant. With the Authorization code grant the end user can access Twitter through your website and give to your website a permanent “grant” to operate in Twitter under some restrictions and on his behalf.
A real life example
Here an example taken from the LinkedIn web app. You are a LinkedIn user and you want to connect your Twitter account so that you can tweet some updates directly on Twitter from within LinkedIn. This is a feature that the LinkedIn devs could have implemented using the Authorization Grant flow. So, in the Setting section in LinkedIn you can press this Change button in the Twitter Settings area:
After pressing “Change”, you enter in a specific area where you can “Connect” your Twitter account:
Here the Authorization Grant flow is now transferring you on the Twitter website where you are asked to enter username and password. You don’t have to share your Twitter username and password with LinkedIn. You are just authorizing LinkedIn to do some stuff for you. The Twitter popup window even tells you in advance what LinkedIn will be able to do with these authorization grant (this list of permissions is the SCOPE).
After you provide to Twitter your username and password, the browser will redirect you back to LinkedIn, that now, without knowing any Twitter credential, can do something on Twitter on behalf of you. You just delegated LinkedIn to operate on Twitter:
Some more details
The Authorization Code grant can be used anytime you connect a user profile to one or multiple accounts from within a website and for instance you authorize the website to access information owned from LinkedIn, Facebook, Twitter, etc….even all at the same time.
This workflows assumes that the developer of the website will store somewhere on the server the authorization code that is exchanged behind the scene between the website (in the above example LinkedIn) and the API you want to connect (in the above example Twitter).
This is because the website has to “remember” some authentication information that has been provided to it, and to use it again in the future to operate e.g with Twitter to publish Tweets on behalf of the user.
Once again, we start from the formal definition in the RFC6749. This is what it states:
The implicit grant is a simplified authorization code flow optimized
for clients implemented in a browser using a scripting language such
an authorization code, the client is issued an access token directly (as the result of the resource owner authorization). The grant type is implicit, as no intermediate credentials (such as an authorization
code) are issued (and later used to obtain an access token).
When issuing an access token during the implicit grant flow, the
authorization server does not authenticate the client. In some
cases, the client identity can be verified via the redirection URI
used to deliver the access token to the client. The access token may
be exposed to the resource owner or other applications with access to
the resource owner's user-agent.
Implicit grants improve the responsiveness and efficiency of some
clients (such as a client implemented as an in-browser application),
since it reduces the number of round trips required to obtain an
access token. However, this convenience should be weighed against
the security implications of using implicit grants, such as those
described in Sections 10.3 and 10.16, especially when the
authorization code grant type is available.
Now, again, let's translate this in some example that you can really "see" and "touch".
This is a typical case where you can use the Implicit Grant. It's main difference with the Authorization code grant is that it doesn't involve any server side code or activity. It’s only between the client and the third party API that the user wants to access.
A real life example with a Web Page
So, they offer a button in the webpage asking to SignIn or Authorize the page to request the list of the files. The end user is supposed to press the button:
Once the end user (that until this moment was anonymous) presses the button, the web client opens another window and redirects him to the Google page where the end-user is requested to type in his Google password. Once again, like in the previous workflow, the user is providing his credential only to Google and no one else.
After the user enters the password, the Sign-In window closes and the Implicit Grant flow redirects him to the previous webpage, where the information stating that now the end-user has authorized this app is passed back. Finally the web page has the authorization, can operate on behalf of the user and potentially display a list of his files stored in google drive.
The demo page unfortunately doesn’t go that far and you can only deduct from the screenshot that the page has now granted access. In these three steps, everything happens between the web client and the third party service (Google Drive). No server code stores any form of persistent authorization here.
A real life example with a Mobile App
I’m going to use one of my favourite mobile apps, Duolingo, to show you an example where during the login the Implicit Grant flow could be implemented.
When you install Duolingo first time on your phone and you launch it you will get a screen like this:
If you press “I already have an account”, you are offered with three cool options:
On the top you can enter the Duolingo username and password. We will see this option later.
At the bottom of the screen, framed in red, you find the entry point for what could easily be an Implicit Grant flow. The user, in this app, can use Google or Facebook and authorize the app to use his Facebook / Google identity. We press then the button “Facebook” and we get the following screen:
It’s important to understand that now, in this step, we are no longer operating inside the app. The app opened a separate windows and now the user is about to login in Facebook and once again grant some kind of authorization to the app Duolingo. The last screen, after pressing LogIn offers a recap of what the user is about to do, performs the login and redirect into the app.
Some more details
The Implicit Grant is very similar to the Authorization grant , but for some technical reasons is not secure as the first one. Another application running on the same machine / device could steal the authorization information exchanged between the client and the third party library and use it. Lots of more information about this and other pros/cons are beyond the scope of this introduction. The best reference I can suggest is in this article.
Resource Owner Password Credential Grant
Again, here is the definition of the flow, from the RFC6749:
1.3.3. Resource Owner Password Credentials
The resource owner password credentials (i.e., username and password)
can be used directly as an authorization grant to obtain an access
token. The credentials should only be used when there is a high
degree of trust between the resource owner and the client (e.g., the
client is part of the device operating system or a highly privileged
application), and when other authorization grant types are not
available (such as an authorization code).
Even though this grant type requires direct client access to the
resource owner credentials, the resource owner credentials are used
for a single request and are exchanged for an access token. This
grant type can eliminate the need for the client to store the
resource owner credentials for future use, by exchanging the
credentials with a long-lived access token or refresh token.
This means that if you have a standalone software (like a Windows app) or a mobile app and the user can type directly in the app the username / password to authenticate and access some web services that are behind the scenes and require authentication.
This grant flow could be implemented every time we have a proprietary app created from a specific company to access the services provided from the company itself, without using any third-party login.
I'll try to mention for you a couple of good examples...
Good examples could be:
- Netflix mobile app asking netflix username / password to access the Netflix world. You would surely enter your Netflix credential in the Netflix app, that's what are the credential for, right?
- Facebook app asking Facebook credential to access Facebook.
Bad examples, meaning examples where the implementation of the Resource Owner Password Credential Grant would be the wrong choice, are
- A "finance manager app" asking you the credentials of your bank account, to connect to the bank account. This should be made with the Implicit Grant!
- A "game app" asking you to type directly in the app the Google credentials to do something with it. The app could steal these credentials, you shouldn't trust any app asking you to do this!
A real life example with a Mobile App
Basically any app that is asking to enter username and password obtained after registration to the same software / website can potentially implement the Resource Owner Password Credential Grant.
To use again Duolingo, we can take this screen as a reference, the initial Sign-In screen:
On the top of the screen you can enter your Duolingo username / password that you received registering on the website. This could be implemented using the Resource Owner Password Credential Grant flow: Duolingo app is asking a password to access to...Duolingo! Fair enough....
Another easy example? Linkedin and its app:
Once again your are entering the LinkedIn credential in the LinkedIn app. There is no trust issues here, as the credential that you will provide to the app can be used ONLY for LinkedIn.
Client Credentials Grant
Lst but not least, here the Client Credentials Grant as formally defined in the OAuth2:
1.3.4. Client Credentials
The client credentials (or other forms of client authentication) can
be used as an authorization grant when the authorization scope is
limited to the protected resources under the control of the client,
or to protected resources previously arranged with the authorization
server. Client credentials are used as an authorization grant
typically when the client is acting on its own behalf (the client is
also the resource owner) or is requesting access to protected
resources based on an authorization previously arranged with the
This time is a bit harder to “show” a real world example as this flow is server based, and some line of code would be more appropriate. Neverthless I will try to give you an idea showing some example where some website COULD be solving a certain problem using the Client Credentials Grant.
Example 1: You have a website and on the server side code you need to access to a backend cloud storage to save / retrieve some data.
Example 2: You have a website and on the server side you want to access a third-party API to retrieve the latest stock-exchange values. The third-party API provides to you, owner of the website, and only to you, the possibility to access this API using some kind of authentication (this would be one case where the parameter Client Secret becomes useful).
A real world example in a web site
Here we have a real estate search engine. It’s a classic aggregator portal: when the anonymous user of this portal makes a search for a property, the portal, behind the scenes, goes and queries many other real estate portals, like the ones framed in red:
Now, probably this specific website is just crawling contents from other portals, I know.
But we can also says that these queries to the other portals could be made using a Client Credentials Grant flow.
There is no end-user involved in the Client Credentials Grant Flow. The server code of this portal (and not the webpage) is making a request using some Web API offered from the other portals (like this Aclado or Anibis and so on) and providing to them some credentials that are, in few words, the username and password of the ”Portal” used to access the WebAPI.
Some more details
The Client Credentials Grant is a flow that doesn’t involve any end-user. It should be only used for a machine – to – machine authentication in order to allow some server side code to access some protected resources like a third-party Web API.
Of course the developer of this server code, the portal in our example, has to register its portal on the provider of the third-party API and get some form of client identification so that he can perform the queries.
Maybe this website is paying some monthly fees to have the permission to query the other portals. Whatever is the exact way they implement, it is clear that NO end user authentication takes place here. The end user doesn’t play any role.
Why this article?
Every author has his own way to explain a topic. Every reader has his own way to learn and understand a topic. While I was learning OAuth2 I have mostly found articles that would go from A to Z, introducing every possible bit and bite of the framework (definitions, roles, flows,etc….) and then trying to assemble these pieces together.
My approach wants to be different, providing you real world examples and trying to explain them. Hope this approach works and I’m looking forward to improve the article using your feedbacks and comments.
2017-02-19: First version.
2017-02-23: Added for each grant the formal definition taken from the RFC6749 OAuth2 specification.
2'17-02-23: Revisited the title to better clarify the content and the scope of the article