Understanding OAuth: Grants
From a practical perspective.
Join the DZone community and get the full member experience.Join For Free
There is a lot written about OAuth and grant types; my goal here is to be a little sparse on the complexity and instead provide practical guidance.
I’ve also seen a lot of examples suggesting if you have a native app, use this, or if you have a web app, use this, etc. I don’t think that is the right way to go about grant types — OAuth is a set of principles, and as such, it can be extended to any type of application and even taken out of the digital realm to physical processes (like signing out a library book).
Instead of talking about native and web apps, I want to reason in terms of actual nouns used in OAuth and then provide non-digital examples to show the relationships.
But first, some vocabulary:
Resource Owner — This is somewhat self explanatory, the rightful owner.
Resource Server — This is the server that provides access to resources, owned by the Resource Owner.
Authorization Server — this is the server that actually holds your credentials, whatever they may be, and in response can provide some information regarding what you are allowed to access on the Resource Server.
Client — the application that wants to interact with protected resources on a resource server.
Some non-digital examples for context:
Your bank is the resource server of your bank account, but you are the resource owner of that account. You are also the client and the client is the resource owner.
The library is the resource owner, resource server of library books, and you are the client. The library is also the authorization server, via the library card.
Which Grant Type to Use?
The above is a flowchart to help you decide on a grant type. This is not a comprehensive view of what is possible, or how OAuth should be implemented — but rather, this is suggestive of what would be the most ideal flow given a particular situation.
The details of these grants are specified in RFC 6749 — but again, this document is more interested in pragmatic choices and less focused on technical implementation details.
Are You a Human?
The question here is whether or not you are a human being or a trusted system. The idea is that a trusted system can keep a secret differently than the way a human can keep it, and System A would not be able to sniff out System B’s secret.
If you are not a human, but some type of automated system, you would choose the Client Credentials Flow. In the Client Credentials Flow, the assumption is that the client can hold a secret — which means it cannot be a mobile app but needs to be a protected system, like a back-end web server. The client provides a client id and a secret to an authorization server, and in return, it obtains an Access Token, which it can use against the resource server.
More importantly, the Authorization Server is aware that it is handing over an access token to an unattended system, and that the Access Token should not have permissions to resources that require the user to be present.
In the non-digital world, this would be an inter-library loan, where a library requests a book from another library. No patron is present, and libraries have a form of establishing trust and accountability between each other. Library A will provide access to its resources to Library B. Library B will eventually provide access to those resources to some patron, but Library A is not concerned with that. Library A is only concerned with trusting Library B.
Do the Client and Authorization Servers Belong to the Same Owner?
The password grant type implies that the client can authoritatively capture the user’s credentials. For example, if Twitter wanted to use Google as the identity provider (IDP), the user should not be asked to enter their Google password on a Twitter client — instead, they should provide their password only to Google. If Google built an app and used itself as the IDP, it could request your password right in its app. More simply put, if the authorization server and the client are controlled by the same entity and are recognized by the user as the same entity, a Resource Owner Password Credentials can be employed. This is a simpler flow and reduces maintenance burden and complexity. Practically, this is the normal “password in exchange for access” flow that we are most familiar with, but as part of OAuth, you end up with a bearer token instead of a session cookie.
A simple example is your library card. The “client,” which in a non-digital institution (i.e. no self-checkout), would be the librarian, belongs to the library, and the information related to the library card, used for verification, also is kept with the library. The librarian is then free to ask what your birthdate is and then check if your answer is true or false. There is no loss of confidentiality as the librarian can plainly see your birthdate on your profile.
Do the Client and the Resource Server Belong to the Same Owner?
Here, the question becomes a little technical and the issue is one of whether it is acceptable for the Access Token to end up with the client (browser or otherwise). If it is OK for the Access Token to end up with the client, an Auth Code flow is not necessary. However, if the Access Token should not end up on the client, then an Auth Code flow is required.
The situation is one where we are using a third-party Identity Provider (IDP), like Google or Twitter, only to establish trust on who the user is. However, we are not interested in accessing Google’s resources directly but are more interested in resolving who the user is, so we can authoritatively give them access to our own resources. In this case, we would use the Auth Code Grant Type flow. This flow ensures that the IDP provided Access Token never surfaces to the client, where it can be stolen and abused. Instead, the Access Token would be used only to establish who the user is and the client will be given a session id, cookie, or completely separate token, to maintain an authenticated state between the client and the resource server.
An Auth Code Grant is probably the most abstract and purely digital authentication flow. It is necessitated by three factors: 1) the authorization server cannot trust the client, because it doesn’t know it, 2) the resource server is not capable to validate identity, and 3) the authorization server provides a one time use code as a form of acknowledgment that this person’s identity has been verified, which then, in turn, can be exchanged for a token that has pre-determined set of information, which is not as sensitive as the information the authorization server needed to establish identity.
For example, if I applied for a Ph.D., the university will ask for a reference. However, it will only accept the reference from the professor directly, and I will simply hand over contact information (email, phone number), and the admission staff will contact the professor directly to obtain the reference. In this case, I call the professor and the acknowledgment allows me to pass on their contact info (access code) to the admission staff, who then will obtain the reference (access token).
Essentially, auth code grant minimizes Confidentiality and Integrity risk. The admission’s committee does not need to snoop around my personal life to establish trust (confidentiality is maintained) and will obtain the reference letter directly from the source (integrity and confidentiality are maintained).
Do the Authorization Server and the Resource Server Belong to the Same Owner?
In the situation where you want to authenticate against Google, so that your application can pull information from Google, belonging to the authorized user, the flow to employ would be an Implicit flow. The user authorizes against an Authorization Server directly and obtains an Access Token, which can be used against the Resource Server. Since the Access Token represents claims of the user directly against resources on the Resource Server, and because the client application itself does not have claims to those itself, the token should go directly to the client application without a server-side intermediary.
Here again, we can look at the example of a library. It issues a library card which then provides access to all the books in the library.
When Should I Use an Implicit Flow Vs. a Public Auth Code Flow?
The question comes down to: What are you planning to do with the Access Token?
If the purpose of the Access Token does not need its own set of scopes against the resource server but is only used to establish identity (and the loss of confidentiality is a low risk — like a user’s playlist on SoundCloud for example), you can use a public client with an Auth Code Flow.
However, if resources belong to the same entity as the authorization server, like accessing your Facebook data, then an Implicit Token, scoped to the specific access the client has permission for, should be used. In this case, the possibility of a server-side component accumulating Access Tokens, via Auth Code Flow, which can be used in the user’s absence should be prevented.
Using the above example for Auth Code Grant and the Ph.D. admission — a public client would imply the professor provides the references directly to me, and I had it over to the admission’s committee. It would still be possible to maintain integrity and confidentiality (i.e. a sealed letter), but it is significantly easier to manipulate (i.e. I could re-seal the letter after modifying it). On the other hand, an Implicit Grant is more like an acceptance letter directly in response to my application.
These are not exhaustive arguments but I hope can help you orient yourself as to what grant type you should pursue. The use of Client Credentials flow is quite obvious, but deciding between Implicit, Password, and Auth Code on public clients can be quite hairy.
The question always comes down to the relationship between the Client, Resource Server, and the Authorization Server. Sometimes, the same organization can have all three but you still need an Auth Code flow — the user may belong to “Digital Banking Company,” but the Investment, Commercial, and Retail banking arms may have published their own apps (clients). In that case, although it is the same organization, an Auth Code flow might be preferable so that passwords don’t proliferate and a weakness in one app is not used to exploit another. Generally speaking, you want to follow the principle of least access as you apply these general ideas to your particular use case.
Published at DZone with permission of Gratus Devanesan, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.