OpenID Connect: Authorization Code Flow

Yasas Ramanayake
4 min readNov 29, 2020

--

OpenID Connect is an authentication protocol that is based on the OAuth 2.0 specification. This can be used by client applications to verify the identity of end-users by using the authentication performed by an authorization server. This is done using a JSON web token called ID token. These ID tokens are requested according to OAuth 2.0 specification and OAuth has 3 main flows designed for different application types;

  • Authorization code flow
  • Implicit flow
  • Hybrid flow

The most commonly used flow is the authorization code flow. This flow is intended for web applications and native applications which has a client/server architecture. Before getting into details lets look at some of the terminologies used;

OpenId Provider(OP) — This is an identity server which implements OAuth 2.0 and OpenID Connect protocols

Relying Party(RP) — Also known as client, this is the application which relies on the identity server for tasks like authentication and authorizing end-users

Scope — Scope identifies the resources that a relying party wants access to.

ID Token — This is the outcome of the authentication process. OpenID specifies ID token to be a JSON web token. ID token must contain at the minimum an identifier for the end-user called the subject claim and can contain additional information like user details and how the user was authenticated.

Access Token — Access tokens are used to authorize access to a resource. These contain information about the client and APIs use that information to grant access to their data.

Refresh Token — Refresh tokens are used to get a new access token once the existing access token expires. These can only be used once and has a longer validity period than access tokens

High Level Overview

Authorization code flow overview [1]

Above diagram illustrates the high-level overview of the steps in authorization code flow. let’s look at each step in detail

1. Authentication Request

RP, also known as the client sends a HTTP GET request to the authorization endpoint of OP. A sample request is shown below,

GET /authorize?
response_type=code
&scope=openid%20email
&client_id=sdlfsdf45dfg
&state=some_state
&redirect_uri=https%3A%2F%2Flocalhost%3A8080

response_type — This is used to define the flow of the request. When initiating authorization code flow this value must be set as “code”.

scope — Lists the scopes that the RP is requesting access to. “openid” scope must be included to initiate the openid authorization flow.

client_id — RP must be registered in the OP before initiating authorization code flow. client id is used by the OP to identify the client.

state — This is a string that can be used by the RP to keep track of the session.

redirect_uri — This indicates the URI to which the OP should send the response. This should match the URI provided when the RP is registered on the OP.

2. Authenticate User

OP will check if the request at step 1 is valid and try to authenticate the end-user. This will typically be done by prompting the end-user to enter their username and password. After authentication, OP will ask the end-user to allow the information requested by the RP to be shared.

3. Return Authorization Code

After successfully authenticating the end-user, the OP will return an authorization code to the redirect URI of the RP by using a HTTP 302 redirect request. This response will also contain a state parameter if the state was present in the authorization request.

https://localhost:8080/?
code=SplxlOBeZQQYbYS6WxSbIA
&state=some_state

4. Retrieve Tokens Using Authorization Code

After receiving the authorization code, RP can send a HTTP POST request to the OP’s token endpoint. This request is sent over TLS . After validating the authorization code OP will return access, ID, and refresh tokens back to the RP. A sample request is shown below

POST /token
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=sdlfsdf45dfg
&client_secret= sfsdfsdgksldgjsd
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Flocalhost%3A8080

grant_type — This must be set to “authorization_code” in the authorization code flow.

client_id — This is the ID provided to RP by the OP when they register.

client_secret — This is the secret provided to RP by the OP when they register. client_id and client_secret values are used by the OP to validate the RP.

code — This parameter contains the code received from the authorization endpoint of the OP

redirect_uri — Must match the redirect URI provided in the request to the authorization endpoint.

After validating this request, OP will return the access, ID, and refresh tokens to the redirect URI of the RP.

HTTP/1.1 200 OK
Content-Type: application/json

{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"

5. Retrieve Userinfo Using Access Token

Additional information about the user can be requested by sending a HTTP GET request to the userinfo endpoint of the OP. The access token must be sent with this request and it is used by the OP to validate the request. A sample request is represented below

GET /userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG

Response from the OP will contain claims that were requested in the authorization request scope parameter. An example success response is represented below

HTTP/1.1 200 OK
Content-Type: application/json

{
"sub": "248289761001",
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"email": "janedoe@example.com",
}

Reference

[1] openid-connect-documentation. 2020. The Authorization Code Flow In Detail. [online] Available at: https://rograce.github.io/openid-connect-documentation/explore_auth_code_flow [Accessed 29 November 2020].

--

--