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 Password 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
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:
. 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
:
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.
Let’s Stay in Touch!
Get the latest on identity management, API Security and authentication straight to your inbox.