Proof Key for Code Exchange

Proof Key for Code Exchange

operate

Proof Key for Code Exchange (PKCE)

This tutorial explains how to use PKCE with a code flow client. To learn how PKCE works read Understanding Proof Key for Code Exchange.

In short we will add an extra parameter that will protect the authorization redirect from beeing hijacked and the authorization code from being stolen.

Pre-requisites

This tutorial builds on the configuration setup in the "Setup and Getting Started" section and the "Setup a Username Authenticator". If you haven't done those steps yet you can visit those guides here:

It's possible to run this tutorial on a custom setup also, but the URLs may be different, as well as the capabilities configured in the profiles.

You will also need a client that can provide access tokens and refresh tokens. If you follow the code flow tutorial, you will have obtained both.

Implementing PKCE in Curity

Using PKCE in Curity is very simple. It is automatically enabled for any client that has the code flow enabled.

While it is not possible to disable PKCE (thus making that client less secure), it is possible to require it (making it more secure).

Setup in Curity

  • WEBUI
  • XML

Visit the Profiles screen and click the Token Service.

Click the Clients page and select a client to work with.

Code Flow Capability

To setup required PKCE for a client it needs to have the code flow enabled:

Admin UI showing a client with code flow enabled

Toggle Require PKCE

  1. Navigate to the Client Application Settings section of a client for which you would like to require PKCE.
  2. Expand the Advanced settings section.
  3. Toggle on Require Proof Key.
  4. Optionally and recommended, disallow the client from using the plain proof key challenge method.

Requiring a client to use a proof key for code exchange in the Admin UI

Of course, these settings can also be configured using the other management interfaces (e.g., the CLI, REST API, etc.). The XML for these settings is shown in the following listing:

<client>
    <id>my-good-client</id>
    <proof-key>
      <require-proof-key>true</require-proof-key>
      <disallowed-proof-key-challenge-methods>plain</disallowed-proof-key-challenge-methods>
    </proof-key>
    <!-- ... -->
</client>

Aside from this, there is nothing more to configure in Curity. Setting up PKCE is that easy :-)

Making requests

To make a PKCE request with the www client that was setup in earlier examples, we need a random proof-key and a verifier. The pseudo code in the Proof Key Overview explains how to obtain these. It's important that they are random for each request.

Here's an example:

  • Code: lszjpzkvqqxuiccquvorhgnxhdmiaholczxqcckotnqkgprymuwhwwutetfd
  • Hashed Code (s256): ps-K7a0ngt1HwZ7N9bK6XyUUJWpcUAkTfetTuZA2qak=

We send the Hashed code in the authorize request, and the Code in the token request to verify the Hashed Code. So the first part of the code flow needs to include the code_challenge and the code_challenge_method=S256 :

https://localhost:8443/oauth/v2/oauth-authorize?response_type=code&client_id=www&code_challenge=ps-K7a0ngt1HwZ7N9bK6XyUUJWpcUAkTfetTuZA2qak=&code_challenge_method=S256

This will now require the backend call to provide the code_verifier or an error will be returned

curl -X POST \
  https://localhost:8443/oauth/v2/oauth-token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code&client_id=www&client_secret=THE_SECRET&code=sE7mpQHlr3Dv19ZNWeO7RnzPOL5lJTEt&code_verifier=lszjpzkvqqxuiccquvorhgnxhdmiaholczxqcckotnqkgprymuwhwwutetfd'

If the wrong verifier is sent, or the verifier is omitted, no tokens will be issued.

Was this page helpful?