We will start with your app. You have created an application which allows your users to edit their images and apply some hip filters.
Your users are happy to upload their pictures to edit them, but you start receiving feedback that it would be easier if they can use the pictures they already have in their preferred cloud storage.
But how can you access the pictures that they have on their cloud storage?
They are all protected by an email and password. Do you ask the user for his email and password and log in his behalf? How secure could this solution be?
Can the user allow the app access to the pictures on her behalf?
Enters oAuth.
oAuth2 allows your application to accomplish the requirements above in a secure way while giving the user full control over what data you can access.
oAuth2 is a Framework that allows you (the application) to access a user's resource (pictures, contacts, bank records, ...) which are protected by another system (Cloud Storage provider, Bank, ...)
oAuth2 has its roots in two RFCs:
- RFC6749 : The OAuth 2.0 Authorization Framework
- RFC6750 : The OAuth 2.0 Authorization Framework: Bearer Token Usage
In oAuth2, there are 4 parties which work together
- Resource Server : The server hosting the protected resource. The protected resource could be pictures, contacts, bank records, ...
- Resource Owner : The user who owns the protected resource and who can grant / deny access to the resource
- Client : This is the app which requires access to the protected resource. A client can be a classic web app, a Single Page app, an Android or iOS app, an IoT device, ...
- Authorization Server : This is the system which will interact with the Resource Owner in order to ask if the client can access the resource
The question that Authorization Server asks the user is usually : Can Resource Owner allow Client access to Protected Resource on his behalf
Usually there are 4 steps :
- Client Registration: Register a Client (your app) with the Authorization Server. This is a one time setup.
- Authorization Server Metadata: Get the Authorization Server information (the different endpoints to be used)
- Authorization Request: Your app asks the question Can Resource Owner allow Client access to Protected Resource on his behalf to the Authorization Server
- Authorization Response: Process the response from the Authorization Server
At the end of the registration, the Authorization Server knows you app and you receive back :
client_id
this is a unique identifier for you app - think of it as a username for your app. This is how the Authorization Server knows that it's your app, and not another app.client_secret
think of it as the password for your app. This is how you'll prove you own the app to the Authorization Server. Depending on your app, you may not receive a client_secret
.
In oAuth2, an authorization server exposes multiple endpoints which are used for different tasks.
The Authorization Server admin can either provide you these endpoints through its documentation or exposes them through
Authorization Server Metadata. This is one URL where you can find all the relevant information about the Authorization Server.
The Authorization Server Metadata offers a better and easier maintanability for your app developers and for the Authorization Server admin.
oAuth2 requires that the user's browser is redirected to the Authorization Server authorization_endpoint
to request for user authorization.
The simplest request is constructed as follows :
In details :
Element | Description |
---|
https://oauth.server/authorize | The authorization_endpoint of the Authorization Server |
response_type | Tells the Authorization Server what kind of response you expect. oAuth2 has multiple response_types (code, token, code token) |
redirect_uri | A URL you have registered with OpenID Provider where the user will be redirected after the authorization. Keep in mind that the authorization could fail. As an example the user could deny that you access all files in a cloud storage |
scope | Represents what kind of access you need from the user. pictures is just an example and it will depend on what resources are available. OpenID Connect defines the offline_access scope which grants the client access to the resource, even when the user is no longer using the client (background processes) |
state | A string that your app creates which the OpenID Provider will return in the response. |
Once the Authorization Server has the answer for the question Can Resource Owner allow Client access to Protected Resource on his behalf, It'll reidrect the user back to your application using the redirect_uri
from the authorization request.
The redirect looks like the following :
In this example, the Authorization Server does not return an explicit answer to your app, but instead it returns an intermediate response - the code
. Authorization Servers are not the most straightforward talkers, but this is the most secure way of communication.
You need to exchange this code for the actual answer you have been looking for since the beginning. You'll call again the Authorization Server token_endpoint
with the following request
POST /token_endpoint HTTP/1.1
grant_type=authorization_code
&code=SOME_VALUE_THAT_DOES_NOT_MAKE_SENSE
&redirect_uri=https%3A%2F%2Fyour.awesome.app%2Fcallback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
The oauth.server will finally respond with the following information
HTTP/1.1 200 OK
{
"access_token": "AN_ACCESS_TOKEN_VALUE",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token" : "A_REFRESH_TOKEN"
}
Now that your application has an access_token
it can request the data it needs. In our example, it could call an API from the cloud storage provider and get the list of all pictures the user has.
It may seem that there are too many steps in the flow, but this is one of the most secure ways which allows the user to be in control.
Keep in mind that oAuth2 allows applications to access data that they do not host. If the data is hosted by the application itself, oAuth2 is overkill.