What is OAuth?

November 18, 2022

Technology & Products

Creating new accounts for all different websites has always been troublesome. Most of them are redundant work, as they all contain the same user information, such as name and phone number.

“Is it possible to allow an app to access my data without necessarily giving it my password?”

OAuth is a standard that tries to solve this problem by providing centralized authorization.

OAuth, which stands for “Open Authorization,” is an open standard for access delegation. It allows you (resource owners) to share information between applications and websites without exposing your passwords. It is widely used, and you probably use OAuth services daily. For example, to log on to GeeksforGeek, you can opt to log on using your Google account. By doing so, you authorize GeeksforGeek to access some of the information on your Google accounts, such as username, profile picture, etc.

OAuth Signing in Example

History of OAuth

OAuth 1.0 protocol was published as RFC 5849, an informational Request for Comments, in April 2010.

OAuth 2.0 protocol was published as RFC 6749, and OAuth 2.0 Bearer Token Usage was published as RFC 6750, in October 2012.

Albeit being built on the OAuth 1.0 deployment experience, OAuth 2.0 is a complete rewrite of OAuth 1.0 from the ground up, sharing only overall goals and general user experience. OAuth 2.0 is not backwards compatible with OAuth 1.0.

How OAuth 2.0 Works

In the OAuth protocol, instead of using the resource owner’s username and password to access protected resources, the client uses an access token. The client obtains the access token from an authorization server upon the approval of the resource owner. For the resource owner to grant authorization to the client, he has to be authenticated on the application first. And since the authentication was only between the resource owner and the application, the third-party client is unable to know any private information of the resource owner.

We can see that implementing the OAuth protocol will significantly simplify the third-party client’s authentication process. All it needs to do is get authorization from the user, request the access token, use it, and get the user information (protected resource). It will not require new users to register accounts or expose their credentials, thus reducing the attack surface and increasing network security.

It is worth noting that OAuth is not authentication. The Auth here is authorization. The user doesn't log in to the application. It only authorizes the third-party application to obtain some of his information.

OAuth’s Authorization Process

Roles

OAuth defines four roles:

Client - The application that wants to access your (resource owner) data and make protected resource requests on behalf of the resource owner and with its authorization.

Resource owner - A user that owns the data in the resource server, wants to use the client’s service and has an account on the authorization server. For example, I am the resource owner of my Facebook profile, and I want to use GeeksforGeeks' service.

Authorization server - The main engine of OAuth. Issues access tokens to the client after successfully authenticating the resource owner and obtaining authorization.

Resource server - The server that stores data the client wants, capable of accepting and responding to protected resource requests using access tokens.

OAuth Protocol Flow

oauth protocol flow

Step A: The third-party application requests authorization from the user

Step B: The third-party application receives an authorization grant, which is a credential representing the resource owner’s authorization

Step C: The third-party application requests an access token using the authorization grant

Step D: The authorization server authenticates the client and validates the authorization grant, if valid, it issues an access token to the third-party application

Step E: The third-party application uses the access token to request the protected resources from the resource server

Step F: The resource server validates the access token and serves the request if valid

Authorization Code and Access Token

There are four types of authorization grant to obtain access tokens from authorization servers. We will only talk about the Authorization Code method here, as it is the safest and most common method.

oauth flow - authorization code mode

Step A: The third-party application lets the user choose an authorization method, such as GitHub, and then redirects the user to the authorization server with parameters such as client_id and redirect_uri

Request sample:

    GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
        &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: server.example.com

Step B: The user logs in and authorizes

Step C: The authorization server redirects the user back to the backend of the third-party application according to the redirect_uri, providing the authorization code

Response sample:

     HTTP/1.1 302 Found
     Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
               &state=xyz

Step D: The third-party application uses the authorization code to exchange for the access token from the authorization server

Request example:

     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
     &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

Step E: The authorization server validates and returns the access token

Sample response from the authorization server:

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }

A Concrete Example

Bob wants to pretty print out his Amazon orders using some software called Rabbit.

Resource owner -> Bob

Client (third-party application) -> Software Rabbit

Authorization Server -> Amazon’s authorization server

Resource Server -> Amazon’s databases for storing order information

Protected Resources -> Bob’s order information on Amazon

OAuth Flow Example - Amazon order

Why Should the Authorization Code and Access Token Be Obtained Separately?

The authorization code and access token are obtained separately to ensure security measures.

In the OAuth2 protocol, the authorization code is a temporary code that the client will exchange for an access token. The code is obtained from the authorization server, where the user (resource owner) has a chance to see what information the client requests and approve or deny the request.

Once the user logs in and authorizes successfully, they are redirected back to the application with a temporary authorization code in the URL.

This authorization code is generally valid for ten minutes and one time only. The short validity period reduces the risk of leaking user information if it gets stolen. In contrast, the validity period of access_token is relatively long, usually 1 to 2 hours. If it leaks, it may impose greater danger to users’ data security.

Moreover, to exchange for an access token, the client will need to provide client ID and client secret in addition to the authorization code. The authorization server needs these parameters to authenticate the client and check that the one requesting the access token is trustworthy. If the authorization code is misfortunately leaked, but the hacker doesn’t have the client ID and client secret, he still wouldn’t be able to obtain the access code. Even if he somehow has the client ID and client secret, he will still need to race with the client-server, because the authorization code is one time only. This mechanism significantly increases the difficulty of potential attacks. If we skip the step of obtaining the authorization code and return the access token directly, the attacker may use the access token to steal user information easily.

OIDC (OpenID Connect)

What is the purpose of using OAuth for authorization? It is to obtain all kinds of information about the user. Why can’t we standardize the output so third-party applications can use it directly?

OIDC does this standardization.

How does OIDC do it? Simply put, it returns an additional JWT format id_token containing the basic user information with the access token. Third-party applications can obtain user information by checking the signing algorithm and verifying the signature on the id_token with a public key.

In addition, OIDC provides the UserInfo endpoint. Third-party services can use the access token to access this endpoint to obtain additional information about the user.

Another feature of OIDC is Single Sign On (SSO) and Single Log Out (SLO). SSO improves usability by enabling the user to have authenticated sessions with different clients without having to provide credentials every time. As long as the user successfully logs in to one application, there is no need to enter the password again when he logs in to other applications.

SLO improves security by ensuring no active sessions are left from an SSO session after the user initiates a single logout. Users only need to log out once and get all sessions terminated, preventing them from being hijacked or misused.

It is worth noting that OIDC is not standardizing a specific authentication method, such as passwords or facial recognition. Instead, it specifies how to delegate authentication to a centralized authentication provider, what we get after authentication - id token, how this token gets verified - JWT format, and what user information this id token contains. So, third-party applications do not need to reinvent the wheel anymore.

APISIX’s Support for OAuth/OIDC

Apache APISIX is an open-source cloud-native API gateway. It is a dynamic, real-time, high-performance API Gateway and you can use it to handle traditional north-south traffic, as well as east-west traffic between services. It can also be used as a k8s ingress controller.

Since APISIX is an API gateway that acts as a proxy for multiple upstream application servers, it is most natural to place centralized authorization and authentication on the API gateway.

APISIX's OpenID Connect (OIDC) plugin supports the OpenID Connect protocol. Users can use this plugin to connect APISIX with many identity providers (IdP), such as Okta, Keycloak, Ory Hydra, Authing, etc., and deploy it as a centralized authentication gateway. OIDC is a superset of OAuth, so this plugin also supports OAuth.

Deployment diagram:

Deployment diagram of apisix and oauth

Configuration Sample: Integrate Keycloak for Authentication with Apache APISIX

Configure Keycloak

ParameterValue
keycloak addresshttp://127.0.0.1:8080/
Realmmyrealm
Client TypeOpenID Connect
Client IDmyclient
Client Secrete91CKZQwhxyDqpkP0YFUJBxiXJ0ikJhq
Redirect URIhttp://127.0.0.1:9080/anything/callback
Discoveryhttp://127.0.0.1:8080/realms/myrealm/.well-known/openid-configuration
Logout URI/anything/logout
Usernamemyuser
Passwordmyrealm
Realmmypassword

Sample code

curl -XPUT 127.0.0.1:9080/apisix/admin/routes/1 -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -d '{
    "uri":"/anything/*",
    "plugins": {
        "openid-connect": {
            "client_id": "myclient",
            "client_secret": "e91CKZQwhxyDqpkP0YFUJBxiXJ0ikJhq",
            "discovery": "http://127.0.0.1:8080/realms/myrealm/.well-known/openid-configuration",
            "scope": "openid profile",
            "bearer_only": false,
            "realm": "myrealm",
            "redirect_uri": "http://127.0.0.1:9080/anything/callback",
            "logout_path": "/anything/logout"
        }
    },
    "upstream":{
        "type":"roundrobin",
        "nodes":{
            "httpbin.org:80":1
        }
    }
}'

When you visit http://127.0.0.1:9080/anything/test after the API is created successfully, you will be directed to Keycloak's login page because you have not logged in:

apisix keycloak login

Enter myuser as username and mypassword as password, and you will be directed to the following page.

apisix keycloak authorized

Visit http://127.0.0.1:9080/anything/logout to log out:

apisix keycloak logout

Summary

In short, the OAuth standard is a popular solution for both applications and users. It provides convenience and security by allowing users to utilize services across multiple platforms without sharing their credentials. Apache APISIX is a popular API Gateway that supports the integration of various identity providers (Keycloak, Ory Hydra, Okta, Auth0, etc.) to protect your APIs.

Read more sessions: Check out more about OIDC in Apache APISIX! Use Keycloak with API Gateway to Secure APIs APISIX Integrates with Ory Hydra APISIX openid-connect plugin

Topics:
OAuth 2.0OIDCAPI Gateway