Relearning OAuth 2.0 ft.Asgardeo

Mikunthan Thumilan
Identity Beyond Borders
12 min readSep 6, 2023

OAuth 2.0 is the authorization framework specification that enables third-party applications to access APIs, on behalf of the end-user or itself. Asgardeo is an IDaaS (Identity as a Service) cloud platform that provides advanced Customer Identity and Access Management capabilities. As a software developer in WSO2 IAM team, I usually work with OAuth2.0 on weekly basis. In this blog, I would like to revisit the specification again.

Consider the following example:

PutBox is an online file storage application(something like Google Drive). Users can store their photos, videos, and files. Besides the PutBox web application, PutBox services are exposed via REST APIs. Since these are sensitive web services Asgardeo protects those endpoints. Recently PutBox collaborated with QuickEdit, an online photo editing application. Now users can directly browse photos from PutBox via the QuickEdit application.

Consider you are one of PutBox’s users. Will you provide your PutBox credentials to QuickEdit to consume the collaborated service? If you ask me the answer is Hell No!!!.

With the help of the OAuth2 framework, access delegation can be handled securely. Let’s see how.

We don’t want QuickEdit to use our credentials to access PutBox. Hence QuickEdit needs a virtual object(a token) that can be used to access PutBox service on behalf of end-users. This virtual object is called an access token.

“Access token is a string representing an access authorization issued to the client”, rather than using the resource owner’s credentials directly.

Even though we don’t want QuickEdit to use our credentials to access PutBox services, we need to grant access to QuickEdit to our resource at PutBox. In other words, QuickEdit needs to be authorized to access our resources on behalf of us.

Authorization grant is representing the resource owner’s authorization (to access its protected resources) used by the client to obtain an access token.

Where does QuickEdit get the access token? Since PutBox trusts Asgardeo, QuickEdit can get an access token from Asgardeo. Since Asgardeo functions as an authorization server for QuickEdit, QuickEdit should be registered as a client in Asgardeo.

Abstract Access Delegation Process

Terms in the brackets are the Roles of these entities in this access delegation process. Let’s look at the diagram in the specification.

Source: Abstract Protocol Flow

Did you notice the difference? Yes, the Client is directly talking to the resource owner via Authorization Request in the specification diagram. In the same section, the specification says,

The preferred method for the client to obtain an authorization grant from the resource owner is to use the authorization server as an intermediary.

as “scope”, “state” and “refresh token”.

Scope

The scope is a list of space-delimited strings. OAuth scopes protect the actions performed by the client on behalf of the user. Consider the following actions and scopes…

Some of the scopes defined by PutBox

Let's see these scopes in action !!!!

QuickEdit wants to Get photos of the users, Add photos to PutBox, and Replace edited photos of the users.

Access delegation process for QuickEdit

Scopes are the OAuth way to explicitly manage the power associated with an access token.

The requested scopes can be controlled by

  • Authorization server — Asgardeo can reject one or more requested scopes in several scenarios. Some of them are
    - The application is not authorized to acquire the scopes.
    - An authenticated user is not authorized to acquire the delegate of the scopes.
    - The requested scope is not valid.
  • End User — The end user can reject one or more requested scopes while providing consent.

Since PutBox trusts Asgardeo, PutBox doesn’t need to worry about…

  • Whether configured authentication mechanisms are performed to ensure user authenticity.
  • Whether the user agreed to provide consent for QuickEdit to perform the mentioned actions.

Putbox can verify the access token validity and allow to perform requested actions.

State

An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client.

State value is used to prevent Cross-Site Request Forgery(CSRF) attacks. Note the keyword opache which means not able to see through (secure random). We will discuss the use of state parameters later in the Authorization Code flow.

Refresh Token

Access tokens usually have a shorter life span. Once it has expired, the client needs to get a new fresh access token. One way is to go through all the steps mentioned in the above protocol diagram but that is not user friendly cause it requires user interaction every time.

Another way is using a refresh token. As the name suggests, a refresh token can be used to get a new access token.

Client obtain new access token using refresh token
  • Since the refresh token is used to obtain an access token, end-user or resource server doesn’t need to be involved in this process.
  • A refresh token will be issued with an access token, and it's optional.
  • Unlike the access token, the refresh token can be reused again.

Enough jibber jabber .. Let’s get our hands dirty ………

We need to register the QuickEdit application in Asgardeo. You can refer to this documentation. Once you register your QuickEdit application in Asgardeo, you can see several application properties and metadata in the protocol section.

  • Client Identifier (Client ID): A unique string that can be used to identify the application in the authorization server. Note that this is not a secret.
  • Client Password (Client Secret/ Client Credential): A secret for the client that can be used for client authentication. Note that using client secret is one way to authenticate clients in the Authorization Server. There are ways which we will look at later.

Client Password should be protected by the client. In the real world, there are some clients (e.g.: JS web applications, SPAs, Mobile applications) which run on top of Browser(user-agent) or Mobile(End-User Device). These clients are unable to protect this client password cause the application source code is downloaded from the server and entirely running on a browser or mobile. These applications are called public clients.

On the other hand, there are other applications that are able to protect credentials. For example, a web application is installed on a web server. These clients are called confidential clients. Client type is important cause client authentication mechanisms and selecting suitable grant types depend on this.

Q1. Is QuickEdit a public client or a confidential client?

ANS: Since QuickEdit is a web application run on, we can consider it as a confidential client. That is why we created a standard web-based application in Asgardeo where we can get client credentials.

There are several ways to get access tokens from the Authorization server which are called authorization grant types.

Let’s see the above grant types and we can decide what's best for our QuickEdit example.

Client Credentials Grant Type

The client credentials (or other forms of client authentication) can be used as an authorization grant when the authorization scope is limited to the protected resources under the control of the client, or to protected resources previously arranged with the authorization server.

As explained in the definition, there is no involvement of the end-user here. Client on-behalf of itself requests an access token and access protected resource. Note that the client is not acting on behalf of the end-user.

Question: What type of clients can use this grant type?

The client credentials grant type MUST only be used by confidential clients.

Why? Because any authentication credentials used by public clients can be accessed by resource owners or user agents. Hence client credential grant type is exclusive to confidential clients.

Clearly, this is a machine-to-machine authentication/authorization cause there is no end-user involvement. One real-world example is using IoT(Internet of Things) devices. If smart devices want to access their data from the server securely, these devices can use the client credential grant type.

Question: Can QuickEdit use this grant type?

You already knew the answer. Even though QuickEdit is a confidential client, the resource it intends to access is not controlled by QuickEdit. Hence the answer is No.

Following is a sample of client credential grant-type access token requests.

From the above table,

  • The authorization header contains Base64 encoded Client ID and Client Secret which helps Authorization server to identify and authenticate the client.
  • “grant_type” should be “client_credentials”
  • “scope” is optional.

Additionally, some servers allow client ID and client credentials as body parameters.

Following is a sample of successful client credential grant-type access token responses.

From the above table,

  • Cache-Control: no-store means this response shouldn’t be cached cause it contains credentials.
  • If the client doesn’t understand the token_type, the client shouldn’t use the token.
  • expires_in is the lifetime in seconds of the access token.
  • There is no refresh token.

Password Grant Type

This grant is considered a less secure grant because end-user credentials were provided to the application. Hence the client on behalf of the user authenticates the user to the authorization server. Here the client is acting on behalf of the user.

Question: What type of clients can use this grant type?

Highly secured/privileged applications usually use this grant type but this is not recommended for public clients and general business applications due to security concerns.

Question: Can QuickEdit use this grant type?

No. QuickEdit is a business application. In this case, it's not ideal to compromise security over user experience. Hence QuickEdit can use this grant type but highly not recommended. PutBox users don’t have control over QuickEdit on what actions going to perform next!!!

Access token request is similar to the above client-credentials grant type request with the following points.

  • “grant_type” should be “password”

Access token response is similar to the above client-credentials grant type request with the following points.

  • A refresh token can be provided from the authorization server.

Implicit Grant Type

So far we looked at 2 grant types and both of them put more focus on confidential clients. So what about public clients? and what about our good old browsers?

Yes, currently we have the CORS(Cross-Origin Resource Sharing) mechanism when the script running in the browser can call third-party domains. Around 10 years ago, we didn’t have that facility, and calling authorization server via POST method is not possible. Implicit grant focused on public clients especially JS scripts which run on the web server and instead of POST method, Implicit grant type uses GET method.

Question: What type of clients can use this grant type?

The implicit grant type is used to obtain access tokens (it does not support the issuance of refresh tokens) and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language.

Question: Can QuickEdit use this grant type?

Yes, QuickEdit can use implict grant type to get access token. But Implict grant type doesn’t provide refresh token.

The authorization server MUST NOT issue a refresh token.

Hence Implict grant type is not an ideal soluction for QuickEdit. Anyway let’s see how an application can get access token via Implicit grant type.

Implict grant abstract protocol

Let’s compare and see what’s different here with above 2 grant types.

Here authorization request will send to authorization endpoint not token endpoint.
- sample authorization request is given below.

GET
https://api.asgardeo.io/t/<org-name>/oauth2/authorize?response_type=token
&client_id=FOWQDN8vho9Tmp9R7xtGjxaQbEEa
&state=randomstate
&redirect_uri=https%3A%2F%2Foauth.pstmn.io%2Fv1%2Fcallback

response_type=token

Client uses “response_type” to inform about grant type. (Did you notice that there is no grant_type here 😜)For Implict grant , response_type=token.

  • In both password and client credential grant types, reply to the authorization request will be access token (for successful request). But here, once the authorization request sent to authorization server it redirects to login page.
  • Since Implicit grant type focuses on public clients, it doesn’t rely on the client authentication mechnisms. On the other hand, it relies on resource owner authentication + authorization and redirection URI.
  • After successful authentication and authorization grant, authorization sends access token with redirection URI in the location.

Redirection URI

— The authorization server MUST require the Public clients and Confidential clients utilizing the implicit grant type to register their redirection endpoint.
— The authorization server SHOULD require all clients to register their redirection endpoint prior to utilizing the authorization endpoint.

In other words, redirection URI is an application specific endpoint which used to send access tokens after successful authentication and authrorization.

Following is location header with sample 302 response (Step 7).

location: https://oauth.pstmn.io/v1/callback?
access_token=ad79deeb-bbc5-3e4b-ba00-e8e99ab6a453
&expires_in=3599
&token_type=Bearer
&state=randomstate
&scope=get_photos

Question: What could be the redirect URI used by above client?

Ans: https://oauth.pstmn.io/v1/callback

Token_Type=Bearer

A security token with the property that any party in possession of the token (a “bearer”) can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession).

Note: This is also a downside. If an attacker posses this bearer token then he/she can access protected resource without further authencation.

Authorization Code Grant Type

Similar to Implicit grant type, authorization code grant type requires to obtain end-user authorization and this grant type also redirection-based grant type. But there are several differences regarding the end points, flow and client type from Implicit grant type.

Question: What type of clients can use this grant type?

This is optimised for confidential clients.

Question: Can QuickEdit use this grant type?

Yes. This is the ideal grant type for QuickEdit. It also provides facility to obtain refresh token.

Authorization Code grant flow

Let see some differences of Implict grant type and Authorization Code grant type based on above diagram.

Following is the authorize request sent in step 1.

GET
https://api.asgardeo.io/t/<org_name>/oauth2/authorize?
response_type=code
&client_id=FOWQDN8vho9Tmp9R7xtGjxaQbEEa
&state=sample
&redirect_uri=https%3A%2F%2Foauth.pstmn.io%2Fv1%2Fcallback

Authorization code

The authorization code generated by the authorization server. The authorization code MUST expire shortly after it is issued to mitigate the risk of leaks. A maximum authorization code lifetime of 10 minutes is RECOMMENDED. The client MUST NOT use the authorization code more than once. The authorization code is bound to the client identifier and redirection URI.

After successful authentication and authorization, authorization code will be sent to client at step 8.

Location:
https://oauth.pstmn.io/v1/callback?
code=cb7916e9-1a4c-34dd-8948-53e97f9a39bc
&state=sample

Once code received by the client, client request for access token from token endpoint.

Its time to discuss about STATE parameter

Check the step 1 and 8. Step 1 is request and step 8 is callback. Why we need to bind this with the state parameter. Checkout following diagram

Instead of using authorization code to exchange for access token, attacker can hold it for latter use.

Then attacker phish the code request into victim’s user agent (eg: via Iframe), if the user agent already has an active user session, when making token request authorization server will skip user authentication and provide access token corresponding to attacker’s code.

With state parameter,

Here the user agent can reject the phishing attack cause the state is different. This attack is called Cross-Site Request Forgery(CSRF).

Conclusion

Question: Can you able to fill following table?

Answer:

Thanks for reading… In next blog, I like to revisit OIDC specifications. Until then see you 👋.

--

--