So many negatives have been brought forth in the past on OAuth 2. Where there might be continuing points of contention, there is one area which seems to be clear: the “Resource Owner Password Credentials Grant” (OAuth 2 Spec, section 4.3) pattern as defined in the OAuth 2 spec is fundamentally superior to HTTP Basic authentication.
This formula describes gaining access to server resources directly. This approach might be utilized when you are securing your own resources; for instance, your mobile app that is accessing your own API.
You are already using Basic auth: Don’t panic!
Just to be clear: Basic Authentication over SSL is actually fairly responsible, from a simplistic security standpoint. When we’re contending with usernames and passwords, Basic auth is a prevalent solution as it’s so easy to implement. The transmission of credentials is encrypted over SSL, and use of the “Authorization” header is ubiquitous in HTTP clients and systems.
However, there are some potential risks with Basic authentication. Primarily, the entirety of the username and password are passed in on each request, simply base64 encoded.
In a man-in-the-middle SSL exploit, the credentials of the user are left wide open. If those credentials are illicitly used, we will have no idea when and where those credentials were compromised. Therefore we’ll have a hard time putting our finger on the attack vector that is compromising logins.
Specifically, there is no token management capability inherent in Basic authentication. This deficiency can make it nearly impossible to limit access to secured resources using Basic auth, without potentially having to disable the user’s credentials completely.
If you’re serious about running a modern defensible web API, you will probably plan for a token management strategy. Token management provides you with a means of tracking each connected device that uses your API.
From “RESTful Web Services Cookbook”:
The access token is an identifier for use by the client to access the user’s resources.
A client in possession of an access token can access the user’s resources as long as
the token is valid. The server may revoke it at any time either due to expiry or due
to the user revoking the permission. The secret is used to sign requests to access
the protected user’s resources.
Access tokens with all grant types
All OAuth 2 grant types are predicated on access token strategies. In my opinion, Aaaron Parecki has done a fine job at summarizing the various OAuth 2 grant types, if you are unfamiliar. Additionally, the “OAuth Bible” from the smart folks at Mashape, outlines grant types very succinctly.
Again, we’re looking specifically at the “password” grant type as a Basic auth replacement. The “password” grant type contains the same username and password that we see in Basic auth, however there is a totally different flow, and some additional elements.
First, the interaction flow is very different from Basic auth. Instead of providing an encoded username and password on every request, we call an endpoint with the requisite elements and receive an access token. From that point forward, the access token is provided in the Authorization header as a ‘Bearer’ value (although there are other means of passing the access token, this is the most common).
An example of the flow to get an access token:
From this point, we can use the “access_token” as supplied in the response as a bearer token in subsequent resource requests.
Mobile: skip the secrets
Keep in mind that on mobile solutions (which are inherently less secure), the ‘client_secret’ is typically not utilized. If the code on the mobile device is analyzed by an experienced coder, they might compromise the client_id and client_secret; only having the client_id makes this marginally safer. In some organizations, unlocking a client_id is only possible when you provide the client_secret.
There are also options to use refresh tokens in the OAuth spec to help mitigate the risk of replay attacks which are not covered here. Selecting appropriate values for TTL (time to live) on access tokens and refresh tokens is an important step in defining your risk profile.
Again, refer to the “OAuth Bible” for a crisp reference on refresh token implementation.
Additionally, the use of the ‘scope’ variable in the token endpoint can be useful to help segregate access privileges. While ‘scope’ isn’t always used in the “password” grant type, it can be useful to help determine a more granular view of how your access tokens are being utilized.
Access token management
From this point forward, this access token becomes a point of control for your operations. If this user account is suspended, or the access token is generating excessive or illicit traffic, the access token can be revoked. Obviously this means you will need some sort of token management infrastructure in place. While this is an investment in your infrastructure, there are a variety of API management providers who can provide this functionality without needing to build it. In fact, companies like 3scale and Apigee have free tiers with fairly high usage limits. Be careful to plan ahead, as API management providers can sometimes make your budget painful when you hit the paid tiers.
While the OAuth 2 “password” grant type is a more complex interaction than Basic authentication, the implementation of access tokens is worth it. Managing an API program without access tokens can provide you with less control, and there is zero chance of implementing an access token strategy with Basic authentication. As long as you stick to forcing SSL usage, either option is secure, but OAuth 2 “password” grant type should give you a better level of control.
Remember that the use of usernames and passwords are always the greatest risk. Both of these techniques have this same risk vector, so don’t forget to implement sound principles authenticating these values, regardless of which solution you choose.