Part 4: OAuth 2.0 PKCE Flow with Azure AD

Shoaib Alam
6 min readAug 25, 2023

--

Proof Key for Code Exchange or PKCE is an extension to the Authorization Code flow to prevent CSRF (Cross-Site Request Forgery) and authorization code injection attacks. It was originally designed for use in mobile applications to prevent malicious background apps from tampering with auth code. It is currently being encouraged as a best practice for authenticating users to Single Page Apps (SPAs) and desktop applications.

The main benefit of authorization code grant type is the transmission of an access token directly to the client without exposing it to others, including the resource owners. It is a two-step process; In the first step the client requests an authorization code from the authorization endpoint of the OAuth provider. In second step the client requests a token from the token endpoint of the OAuth provider using the authorization code from previous step along with client_id and client_secret. To get client_id and client_secret the client must register with the OAuth server. After successful registration the client receives a client_id and a client_secret.

The purpose of the client_secret is to let an instance of client software to authenticate itself to the authorization server. client_secret is a configuration time secrets and every copy of client application should have access to it. Which doesn’t make it very secret particularly in case of public clients like native and single page applications (SPA). In either case, each copy of the client software is identical and there are potentially many instances of it.

It is possible for an attacker to reverse engineer a native application to gain access to the client_secret. In the case of single page applications, the client_secret is available in the web code, openly accessibly in the browser. With a client_secret and authorization code, a malicious application can effectively impersonate the original application for which the authorization code was issued. This is called an authorization code interception attack.

To mitigate such attacks against public and native clients, Proof Key for Code Exchange (PKCE, pronounced as “pixie”) is an extension to the OAuth 2.0 protocol that prevents authorization code interception attacks. It is a simple, lightweight mechanism that can be implemented in any application that requests an authorization code.

Proof Key for Code Exchange (PKCE)

Code Challenge

In place of the client_secret, the client creates and records a secret called the code_verifier. The client then computes code_challenge based on the code_verifier.

The code_challenge can be either the same as code_verifier or the SHA- 256 hash of the code_verifier. SHA-256 is strongly preferred as it prevents the verifier itself from being intercepted.

The client sends the code_challenge and an optional code_challenge method (a keyword for plain or SHA-256 hash) along with the regular authorization request parameters to the authorization server.

The authorization server responds with an authorization code as usual but records code_challenge and the code_challenge_method (if present). These are associated with the authorization code that was issued by the authorization server.

Code Verifier

After receiving an authorization code, the client makes a token request to a token end point as usual, but the request also includes the code_verifier that it previously generated. The server computes the code_challenge and compare its value with original value associated with authorization code.

If everything matches up, the authorization server returns an access token (and id token in case of OpenID Connect) as normal. An error response is returned if they aren’t equal.

Sequence Diagram

Following sequence diagrams covers a use case for a specific endpoint.

Authorization End Point

Token End Point

Register an Application with Azure AD

In Part 2 I already registered two applications DemoClientApp01 and DemoWebApp in Azure AD. I am going to use the same applications to get access token for the Authorization Code Flow with PKCE.

I also assume that Postman is downloaded and installed. For Authorization code flow with PKCE needs two extra parameters to the authorization code grant: code_challenge and code_verifier. The code_challenge is a Base64-encoded SHA-256 hash of the code_verifier. The code_verifier is a cryptographically random string. Both code_verifier and the code_challenge is generated by the client. I am going to use the following site to generate code_challenge and code_verifier.

https://developer.pingidentity.com/en/tools/pkce-code-generator.html

Or you can use the following site as well.

Online PKCE Generator Tool (tonyxu-io.github.io)

Add a platform for single-page application.

From Azure Active directory navigate to DemoClientApp01 and add Redirect URI from Authentication > Add a platform > Single-page application. I am going to use https://oauth.pstmn.io/v1/callback

Authorization code using GET request.

In postman add a new GET request with following parameters:

HTTP Request: GET

URL: https://login.microsoftonline.com/<<your tenant ID>>/oauth2/v2.0/authorize

Query Parameters:

To get a token, we need the authorization code. The easiest and quickest way to get an authorization code is copy and paste the URL from above step in a browser and follow the prompts to login using username and password.

Once the user is successfully authenticated, copy the URL and extract only the code from it.

Access token using POST request.

In postman add a new POST request with following parameters:

HTTP Request: POST

URL: https://login.microsoftonline.com/<<your tenant ID>>/oauth2/v2.0/token

Body:

You might need to add an Origin Header as Origin: *

Press a Send Button and you will get an JWT access token in the response.

Decode JWT Access Token

Let’s open the website jwt.io. and copy and paste the token acquire in the previous step.

--

--