Authorization code flow with PKCE

📘

Prerequisite

  1. Setup the OpenID Connect custom application

The authorization code flow is susceptible to code interception attacks where the attacker intercepts the authorization code returned from the authorization endpoint within a communication path not protected by Transport Layer Security (TLS), such as inter-application communication within the client's operating system.

Once the attacker has gained access to the authorization code, it can be used to obtain the access and ID token.

To mitigate this attack, the PKCE flow utilizes a dynamically created cryptographically random key called "code verifier." A unique code verifier is created for every authorization request, and its transformed value, called "code challenge," is sent to the authorization server to obtain the authorization code. The authorization code obtained is then sent to the token endpoint with the "code verifier," and the server compares it with the previously received request code so that it can perform the proof of possession of the "code verifier" by the client. This works as the mitigation since the attacker would not know this one-time key since it is sent over TLS and cannot be intercepted.

Code verifier and code challenge

Code verifier is a high-entropy cryptographic random STRING using the unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" (refer to https://www.rfc-editor.org/rfc/rfc3986#section-2.3) , with a minimum length of 43 characters and a maximum length of 128 characters.

code challenge is derived from the code verifier by using one of the following transformations on the code verifier:

plain
code_challenge = code_verifier

S256
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

How does it work?

12151215

In this flow,

  • The client application (or relying party), the bank, sends an authorization request with the code challenge and code challenge method to CyberArk Identity, which acts as the authorization server.
  • CyberArk Identity authenticates the user and redirects the user with an authorization code.
  • The bank sends a token request by passing the authorization code and code verifier.
  • CyberArk Identity validates the token request and returns the access and ID tokens. Optionally refresh tokens are also returned.
  • Bank uses the ID and access token to make further calls to the resource server and to validate the user.

Integrate CyberArk Identity's authorization code flow with PKCE

An authorize request is sent from a user's browser (the client application) with the code_challenge and code_challenge_method to the authorization server.

GET {tenant_url}/oauth2/authorize/{application_id}?redirect_uri={redirect_uri}&client_id={client_id}&response_type=code&code_challenge=1XnNCHd73dNHQcmyzG...QY&code_challenge_method=S256

If the user is already authenticated, then the authorization server redirects users to the callback URL with the following code:

<html><head><title>Object moved</title></head>
<body>
    <h2>Object moved to <a href="{redirect_uri}?responseType=code&amp;code=WXlxkM9dSk...">here</a>.</h2>
</body>

</html>

The client application sends the token request with the code_verifier and the authorization code to the authorization server.

POST {tenant_url}/oauth2/token/{application_id} HTTP/1.1
Content-Type: application/x-www-form-urlencoded

Body parameters should be sent as form urlencoded

redirect_uri={redirect_uri}&code=HsOynOzaKL_yCo_-cJhh4xM...&grant_type=authorization_code&client_id={client_id}&code_verifier={code_verifier}&nonce=abc

The authorization server responds to the client application with an access token and ID token and then the user is logged in to the client application.

{
    "id_token": "eyJhbGci...",
    "refresh_token": "A2GUm...",
    "access_token": "eyJhbGc...",
    "token_type": "Bearer",
    "expires_in": 18000,
    "scope": <scopes>
}

👍

Integrate authorization code flow using CyberArk Identity SDKs

CyberArk Identity provides SDKs to integrate authorization code flow into your applications.