Daniel Lindau of Curity provides an overview of important OAuth flows and abilities
The API space requires authorization in order to secure data – this is a given in the modern era. Accordingly, implementing the correct authorization system is vitally important, perhaps even more important than the API it is meant to handle authorization for.
OAuth is a powerful solution for many providers. As with any tool, however, it’s only as powerful as it is understood by the user who chooses it. Understanding what OAuth is and, at the very least, having a general overview of each particular flow is extremely important. In this piece, we’re going to look at OAuth, and give a brief rundown of each flow type. We’ll look at when each flow is appropriate, and what its specific use case is.
What is OAuth? What is a “flow”?
While it might go without saying, there is some benefit to stating upfront exactly what OAuth is. OAuth is an open standard for delegation and authorization on the internet. The use case for OAuth is usually a client that needs to access some resource on behalf of the user. To accomplish this delegation, an Access Token is issued. The Access Token represents the consent the user gave, allowing the client to access its data on behalf of the user. The requesting, granting, and life management of this token is often referred to as a “flow”, a term which will be used substantially throughout this article.
While the first version of OAuth was initially created in 2007 as a means to handle authentication on the Twitter API, it has since become extremely popular in a variety of applications with scopes ranging from enterprise-level codebases to home projects. The second version, OAuth 2.0, has become the de facto standard for securely protecting your APIs.
Flows Differ On Use Case
The OAuth specification allows for several ways of obtaining and validating tokens, and not all flows are meant for all types of clients. The OAuth specification talks about public and private clients, which roughly translates into the clients’ ability to keep its credentials safely stored. Private clients are typically applications with a backend that can keep a secret to use for authenticating. Public clients have no means of securely keeping a secret, for instance, a single page application that usually doesn’t have a backend.
For instance, web applications with a backend are considered private clients, and single page applications are considered public. The backend can securely keep the secret, while the SPA has everything out in the open.
Mobile clients are a bit trickier to classify since they are generally pretty good at keeping a secret, but it’s hard to give them one. The way the apps are distributed through app stores makes it harder for clients to authenticate in a way for the OAuth server to trust that it is the correct application. For this reason, they are to be considered public. By using other means of getting credentials, like the Dynamic Client Registration, it can be made into a private client. But more on that later.
There are four base flows for obtaining tokens in OAuth, and a number of flows that are defined in sibling specifications. Here I’ll describe the base flows and others that I believe to be important.
1. Authorization Code Grant
The Authorization Code Grant, or Code Flow, is the most widely spread OAuth flow. To obtain a token using code flow, the clients send an authorization request to the OAuth server by simply redirecting the browser to the server. The OAuth server makes sure that the user is authenticated, and prompts the user to approve of the delegation. When the user approves, a short-lived code is issued to the client. This code can be considered a one time password, or a nonce. The client receives this code, and can now use it in an authenticated backend call – outside of the browser – and exchange it for the token.
One thing to mention here is that the user only will enter its credentials to the OAuth server. The user won’t have to give the credentials to the app, it simply enters them to the server it already knows and trusts. This is one thing that OAuth set out to solve.
The other benefit is that the token owner passes the browser, which makes it harder to steal, and since the call to exchange the token is authenticated, the server can be sure that it delivers the token to the correct client.
Usually, the code flow will also allow you to receive a Refresh Token, which allows the client to get new access tokens without involving the user. Even after the Access Token is expired. The code flow should only be used by private clients since the client needs to authenticate itself when exchanging the code.
2. Implicit Flow
The Implicit flow is a less complicated flow than the code flow. It starts out in the same way as the code flow, with the client making an authorization request to the OAuth server. The user authenticates and approves of the delegation, but instead of issuing a code, the OAuth server responds with an Access Token.
The downside here is of course that the token is visible in its entirety, and since it is in the browser, the client needs to handle the token in a way that could make it vulnerable.
Implicit flow is made for public clients that cannot authenticate themselves. So the trust here instead lies in a parameter called redirect_uri. The OAuth server needs to have registered a URL for the client, where the response will be sent. The response will only be sent there, so if a malicious application fools a user into initiating a delegation process, the response will always go back to the real application.
Since this is for public clients, a Refresh Token won’t be issued. That means that new Access Tokens can only be received by involving the user.
3. Client Credentials Flow
In the Client Credentials Flow, there is no user. It is a flow that is strictly for server-to-server communication. A server needs to access an API as itself. Therefore, there is no browser involved, and a private client is needed. To get an Access Token, the client simply passes its credentials to the OAuth server and receives the token.
No Refresh Token is issued in this flow since the client can retrieve a new Access Token using its credentials anyway.
4. Resource Owner Password Credentials Flow
The Resource Owner Password Credentials Flow is pretty simple. The client collects the credentials from the user and passes them together with its own client credentials. The server responds with an Access Token and optionally a Refresh Token. Simple right? But there’s a ‘but’, and it’s a big one.
ROPC is a flow that defeats one of the purposes of OAuth; that the user has to give away its credentials to the app and thus has no control over how the client will use it. The flow is not recommended for use if you can use something else. It’s only specified in the specification to allow for legacy or migration cases. It should be used with care. An example could be an enterprise desktop application, that is not easily updated but needs to have access to the API platform.
We don’t recommend the use of it, but if you really need to: The flow is for private clients only, and the client could get a Refresh Token.
5. Dynamic Client Registration
While not one of the flows in the core OAuth Spec, Dynamic Client Registration solves an important use case for mobile clients. Since mobile apps are distributed through app stores, it’s hard to give them a credential to uniquely identify itself, and mobile clients are therefore usually labeled as public.
Dynamic Client Registration tries to redeem that by specifying means for a client to register itself, and request a unique credential upon installation. It works by letting the client send a registration token to the OAuth server, which generates a set of credentials and returns them to the client. These credentials can then be used in a code flow, and the client can now authenticate itself.
The registration token can be obtained in multiple ways. Either by letting the user authenticate itself in an Implicit flow or by using the Client Credentials flow with a pre-distributed secret.
Outside of the mobile case, Dynamic Client Registration can be very useful for API management platforms, that need to be able to create clients for the OAuth server.
6. Assisted Token Flow
The Assisted Token flow is a draft that is not part of the base flows, but it is worth mentioning. It is a sibling specification to OAuth that tries to make it easier for Single Page Applications to obtain tokens. For those type of applications, it can be hard to handle Implicit Flow, since it relies heavily on redirects. Instead, Assisted Token Flow defines a similar flow to Implicit, that instead use iframes and postMessage as means of communication.
Introspection is the way to ask the OAuth Server if a token is valid. Access Tokens are usually passed around by reference, meaning that they do not mean anything for anyone but the OAuth server. The introspection clients are usually an API or an API gateway of sorts. Introspection is a simple authenticated call, where you send in a token, and the response is the data that belongs to the token, such as the expiration time, subject, etc.
Revocation is one of the powers of OAuth. Without OAuth, a user that gave away its credentials to an application has no means of retracting that consent. The only way is to change the password, which might have bigger side effects than disallowing the app to access the user’s account.
With OAuth, the user can decide to recall the consent whenever by revoking the token. In OAuth, you have two options for revocation, you can revoke the Access Token, which could be seen as ending the current session. If there is a Refresh Token, it would still be valid. Revoking the Refresh Token would make the Refresh Token invalid, and any active Access Tokens that came with it.
It is the client that performs the actual revocation with an authenticated call. Even though it’s authenticated, public clients can be allowed to perform revocation.
Why Distinguishing OAuth Flows Is Important
It can seem like there are a lot of similar flows in OAuth, but each flow has its specific use case. By these essential flows, you should be able to pick the flow(s) that match your application and scenario.
While this is all generally high-level, each flow could warrant its entire own piece. For additional reading, please review the various pieces that we’ve done previously concerning OAuth and OAuth flows. If your interested in knowing more about the basics of OAuth and can be in Stockholm the 22nd of October, please join our workshop at the Nordic APIs Platform Summit.