Integrate the authorization code flow with PKCE

This topic explains how to use an authorization code flow with PKCE with CyberArk Identity.

Overview

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 a code verifier. A unique code verifier is created for every authorization request, and its transformed value, called the 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.

Before you begin

Set up the OpenID Connect custom application.

About the code verifier and code challenge

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

A 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 it works

In this flow:

  1. 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.

  2. CyberArk Identity authenticates the user and redirects the user with an authorization code.

  3. The bank sends a token request by passing the authorization code and code verifier.

  4. CyberArk Identity validates the token request and returns the access and ID tokens. Optionally refresh tokens are also returned.

  5. The bank uses the ID and access token to make further calls to the resource server and to validate the user.

Integrate theCyberArk Identity 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, 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>

}