Understanding OAuth 2.0
Identity delegation has been revolutionized by OAuth 2.0. It is primarily responsible for solving the problem of access delegation.
Say you want a third-party application to read your Facebook status messages. You want to grant third-party applications access to your Facebook wall. To accomplish this, you can share your Facebook credentials with the third-party application so it can directly access your Facebook wall. In this case, access is delegated by credential sharing. Even though this solves the access delegation problem, the third-party application can then use your Facebook credentials to do whatever it wants, which in turn creates more problems!
With OAuth 2.0, you do not have to share your credentials with third-party applications, but only a time-bound temporary token that is only good for a defined function.
OAuth 2.0 Actors
In a typical OAuth flow, there are four actors.
- Resource Owner — An owner of resources. According to the preceding use case, the resource owner is the Facebook user who owns the Facebook wall.
- Resource Server — Protected resources are hosted here. As shown in the preceding scenario, the server that hosts the Facebook API is the resource server.
- Client — This is the application that wants to access a resource on behalf of its owner. The client in the preceding use case is a third-party web application.
- Authorization Server — As a security token service, it issues OAuth 2.0 access tokens to client applications. The authorization server in the preceding use case is Facebook itself.
Grant Types
OAuth 2.0 grant types define how a client can obtain an authorization grant from a resource owner to access a resource on their behalf. OAuth 2.0 refers to this well-defined purpose as scope. A client application’s scope determines what actions it can perform on a given resource.
The OAuth 2.0 core specification introduces four core grant types.
- Authorization Code Grant Type
- Implicit Grant Type
- Resource Owner Password Credentials Grant Type
- Client Credentials Grant Type
Authorization Code Grant Type
In general, it’s recommended for web or native mobile applications that can open a web browser. The authorization code grant type is initiated by the resource owner who visits the client application. Client applications must be registered with the authorization server.
Client applications generate the following HTTP request when redirecting users to the authorization server’s authorize endpoint:
https://www.facebook.com/v8.0/dialog/oauth?response_type=code,granted_scopes&client_id=672176943231521&redirect_uri=https://callback_url.com&scope=public_profile,email
An OAuth 2.0 authorization server’s authorize endpoint is well-known and published. Response_type must be code. The authorization server knows that the request is for an authorization code. The client_id identifies the client application. As soon as the client application registers with the authorization server, it receives a client_id and a client_secret. During client registration, the client application must provide a URL under its control as the redirect_uri, and in the initial request, the redirect_uri parameter must match the one registered with the authorization server. On the approval screen, the scope parameter indicates to the authorization server the level of access the client needs to the target resource or API.
The callback URI would look like this
https://callback_url.com/?code=AQDpbgl-BQzleWPaxmsNe_z_kkfYiiZrZHOwOCBxS5XdSXRNaK5B9tIoYh8IrAsf7KbsGskUwSrln-Mhr64vV0IBg-ZWX5cO-Le0Ao4NqMkFm6ajXTHTRfP08Deqnxi-hJ35-jqjYxuIdby3JifZ64T3TMEiDx2g46riJ5_3FYKMJf9iFjwFRPL1-1c7X9HxAibr
An authorization code returned by the authorization server acts as an intermediate code. This code maps the end user or resource owner to the OAuth client. It is possible for the OAuth client to authenticate itself to the token endpoint of the authorization server. Before exchanging the code for an access token, the authorization server should verify that the code was issued to the authenticated OAuth client.
Implicit Grant Type
JavaScript clients running in the web browser typically use implicit grants to acquire access tokens. For JavaScript clients, we do not recommend using implicit grant types, but rather authorization code grant types without client authentication.
Note: Never use it in a production deployment.
JavaScript initiates implicit grant flow by redirecting the user to the authorization server. Response_type indicates to the authorization server that the client expects a token, not a code. The implicit grant type does not require the authorization server to authenticate the JavaScript client; it only needs to send the client_id. In the request, redirect_uri is optional; if it is present, it must match what was provided at client registration.
https://authz.server.com/oauth2/authorize?response_type=token&client_id=672176943231521&redirect_uri=https://callback_url.com
The following response is returned. The implicit grant type sends the access token as a URI fragment and does not provide a refresh mechanism.
https://callback_url.com/#access_token=33cac93e1d29343535373dbfb460&expires_in=3600
Resource Owner Password Credentials Grant Type
The resource owner must trust the client application under the resource owner password credentials grant type. Client applications require credentials directly from resource owners.
Client Credentials Grant Type
This grant type makes the client the owner of the resource. An access token is included in the authorization server response. Client credentials grant types do not return refresh tokens, unlike resource owner password credentials grant types.
The client credential grant type is primarily used for system-to-system interactions without an end user involved.
Refresh Grant Type
Although the implicit grant type and the client credentials grant type do not come with a refresh token, the other two do. A refresh token can be used to extend the validity of an access token without involving the resource owner.
Pick the Right Grant Type
To select the right grant type for those applications, we must first determine how the client application will access the OAuth secured API: independently or on behalf of an end user. When the application wants to access the API by itself, we should use the client credentials grant type, but if not, we should use the authorization code grant type.
Implicit and password grants are now obsolete.
OAuth 2.0 Token Types
OAuth 2.0 isn’t tied to any token type. If needed, you can introduce your own token type in OAuth 2.0. The client must understand the token_type returned in the OAuth token response from the authorization server. The authorization server can add additional attributes/parameters to the response depending on the token type.
OAuth 2.0 has two main token profiles:
- OAuth 2.0 Bearer Token Profile
- OAuth 2.0 MAC Token Profile
Nowadays, almost all OAuth 2.0 deployments are based on the OAuth 2.0 Bearer Token Profile.
OAuth 2.0 Bearer Token Profile
To avoid losing bearer tokens in transit, bearer tokens must always be sent over Transport Layer Security (TLS). Clients can communicate with the resource server in three ways after obtaining the bearer access token from the authorization server.
HTTP Authorization headers are the most popular way to include the access token.
It is also possible to include the access token as a query parameter. JavaScript client applications mostly use this approach.
The access token can also be sent as a form-encoded body parameter.
OAuth 2.0 Client Types
OAuth 2.0 identifies two types of clients:
- confidential clients — Clients are capable of protecting their own credentials (the client key and the client secret).
- public clients. — Public clients can’t
Three types of client profiles are defined in OAuth 2.0:
- Web applications — Web applications are considered to be confidential clients, running on a web server: end users or resource owners access such applications via a web browser.
- User agent–based applications — Applications that use a user agent are considered public clients: they download code from a web server and run it on the user agent, such as JavaScript running in the browser. JavaScript clients cannot protect their credentials — the end user can see anything.
- Native applications — Native applications are also considered as public clients. The end-user has control over native applications, so any confidential data stored in them can be extracted. Examples include Android and iOS native applications.
References
Book — Solving Identity Management in Modern Applications