OAuth2 should ring a bell. Nearly everyone has heard about it, although not necessarily in superlatives.
The standard is a bit tangled and not so easy to understand at a first sight. Reading the specification might be quite painful at times; so many complications, tokens, credentials and even uncle Google, who usually has all the answers, can’t really handle it this time. Before you read the whole Internet, let’s try to disentangle things together.
Should I really try to use it? – a quick introduction to OAuth2
If it’s really so awful, do I really need that battle? I have usernames and passwords that have been working pretty well for years and cryptography is my secret superpower. C’mon, let’s face up to the truth.
The OAuth2 is an open authorization standard that enables third-party applications to obtain access to server resources either on behalf of a resource owner (in most cases – the client application’s end-user) or on an application’s own behalf.
Typically, in the client-server authentication model, client requests access protected resources by providing the resource owner’s credentials. Sharing credentials with third-parties raises some security problems:
- The credentials need to be stored somewhere in the client application.
- The server must support password authentication.
- In case resource owner credentials change, access to all third-party applications must be revoked.
- If compromised, the third-party application may expose the resource owners credentials.
- The access duration and scope are practically impossible to control.
All the above concerns are addressed by the OAuth2 framework. It eliminates the need of disclosing resource owner credentials to the client by introducing an authentication layer that enables access to the resource server with an access token. The token is issued by an authorization server (trusted by the resource service) with the resource owner’s consent. This way the client application does not need to store (and in most cases even know) the end-user’s password.
Thus, do you really need to use it? No, you don’t. However, if you want to become a security rock star and play in the same league as social media developers, you should really take it under consideration.
The roles – who is who in OAuth2
There are four roles defined by the OAuth2 specification:
- Resource Owner – an entity capable of granting permissions to protected resource. It can (but doesn’t have to) be an end-user.
- Client – a third-party application that requests a protected resource on behalf of and with the consent of a resource owner.
- Authorization Server – a service that authenticates a resource owner and issues an access token upon receiving authorization.
- Resource Server – a service that hosts protected resource and responds to requests which contain a valid access token.
The abstract OAuth2 flow is illustrated in the following figure:
In fact, the specification does not define the interaction between an authorization and a resource server very tightly. They may be combined into one or work as two separate entities. In the next blog post I will present both approaches developed in the one true technology. 😉
Why on Earth did they complicate this so much? – a word about OAuth2 grant types
An authorization grant serves as a special type of credential representing a resource owner’s authorization and is used by a client application to obtain a token. The OAuth2 standard describes four main grant types (authorization code, resource owner credentials, implicit and client credentials) and an additional mechanism to define custom ones.
Authorization code is typically used when the resource owner is an end-user and they are using a browser (also embedded) as a user-agent. In order to obtain authorization, the client directs the resource owner to the authorization server, which (after successful authorization) redirects them back to the client application supplying an authorization code. The most important thing about this grant type is the fact that the access token remains private as it is not exposed to the resource owner.
Resource owner credentials can be used to obtain an access token straightaway. In this grant type the client application asks for resource the owner’s credentials themselves and then sends them to the authorization server together with its own credentials. This grant type should only be used with trusted clients (for example a service’s own mobile applications) and when there is no possibility to use other authorization grant types (such as an authorization code). It is worth mentioning that the resource owner’s credentials supplied to the client not need to be stored; they are only used once to perform a single request and exchanged for an access token.
Implicit grant type is similar to the authorization code grant, optimized for in-browser clients (such as script languages applications). As its name indicates, the flow is implicit and the access token is issued directly to the client. This grant type should be used very carefully since the access token is received as a URL parameter and can be revealed to third-parties. What is more, during implicit flow, the authorization server does not authenticate the client and hence there is no method provided to determine what client the access token was granted to, which creates an additional threat.
Client credentials are used in machine-to-machine authorization, when the client is acting on its own behalf or when it is accessing resources based on a previously established authorization.
As you can see, the whole thing may seem a little hazy at first, but in fact every one of the grant types has its own application area. Usually, there is no need to worry about all of them, you just have to pick the one that suits your needs and go for it.
Client credentials – an additional pair of keys
In OAuth2, clients with issued credentials (not trusted ones) must authenticate themselves in order to be able to make a request for tokens. The authentication helps to enforce that refresh tokens (which will be disused later) and authorization codes are issued for the clients they were intended for. It also enables the possibility of disabling the client or revoking the whole set of refresh tokens in case the client is compromised.
Access token – the key to the gate
Finally, the cherry on the top; the award for the mind distortion you just put yourself through – the access token. The access token represents an authorization issued to the client by the authorization server. It may contain either the authorization information itself or only some information that may be used to retrieve the authorization. The access token is understandable by the resource server and can replace other authorization methods used to access protected resources. It has a limited lifetime and is tied to a specific scope of access.
Since you already have an access token and probably see a light at the end of the tunnel, let’s obfuscate things a little bit again. But don’t you worry, this is really for a good reason. I am introducing… a refresh token! The refresh token is a credential used to obtain a new access token when the current one expires or becomes invalid or to retrieve additional tokens of narrower scopes. It is optional. If the authorization server supports this grant, it is issued along with the access token.
Access token vs refresh token – do I really need them both?
No, you don’t (since a refresh token is optional), but you will probably want to have both of them either way. Since the access token is so powerful it has a limited lifetime, in case it is leaked. That is the reason the refresh token enters the game; after all, nobody wants to authorize themselves again and again. Refresh tokens have an extended duration and serve to prolong access to protected resources by obtaining a subsequent, short-lived access token. Even if a refresh token is compromised it is useless to the attacker, unless they have client credentials too. Pretty smart, huh?
Access token scope
Since not everyone can have superpowers, the OAuth2 standard provides a mechanism to restrain access to the resource service – the scope. The granted scope depends on the authorization server policy and the resource owner’s orders. The authorization server can deny the scope requested by a client and issue another one, of which the client must be informed. If the client doesn’t specify the scope during an authorization request, the authorization service may issue a pre-defined one or completely refuse authorization.
In this post we covered the basic theory needed to implement the OAuth2 standard. I hope you enjoyed it and invite you to the next chapter, even if you are not a Java developer. ;)