search
tutorials

Security, Apps, and Access Tokens (PKCE)

Apps such as Native/SPA apps store their code on user devices and browsers. That can be a risk when you include the client secret in that code. With the Proof Key for Code Exchange (PKCE) (pronounced pixie), ForgeRock Identity Cloud Express lets you acquire access tokens without that app client secret.

Even though the code for web apps is stored on servers, PKCE can also reduce risks for web apps.

Users typically don’t sign in to service (M2M) apps. So we don’t include M2M PKCE flows in this tutorial.


For a detailed analysis of PKCE, including a flow diagram, see Keeping Your Apps Secure with PKCE.

Prerequisites

You’ll need to set up a user. You can do so through the console. Or, you can use a REST call like the one shown in the Users section of our API documentation.

You’ll also need to set up one of the following apps. If you haven’t done this, the links direct you to relevant getting started guides:

You can also set up these apps in the console Applications menu:

alt text

When you set up an app, the REST calls that follow assume that you’ve set up a redirectUri of https://example.com/homeLogin/.

With these prerequisites, you can set up Native/SPA and web apps to use PKCE to enhance the security of you access tokens.

For a working example of these REST calls, see our API Documentation and find our PKCE-based Authentication REST calls. Download our Postman collection from our GitHub Repository.

PKCE and Native/SPA Apps

To get an access token using PKCE, you can run the following REST calls for Native/SPA apps:

1) Get an SSO token. With the username and password of a regular user, you can get an SSO token with the following REST call:

content_copy COPY

curl -X POST \
  https://openam-{tenantName}.forgeblocks.com/am/json/realms/root/authenticate \
  -H 'Accept-API-Version: resource=2.0,protocol=1.0' \
  -H 'X-OpenAM-Username: {username}' \
  -H 'X-OpenAM-Password: {password}' \

2) Substitute appropriate values for {tenantName}, {username}, and {password}.

The output includes the tokenId, the SSO token for the given user. Our Postman collection includes a script that copies the SSO token to the ssoToken property:

alt text

3) Get an authorization code. Once you have a verified authorization code, you can exchange it for an access token.

4) To set up the following REST calls, find your values for the following properties:

Property Description
tenantName Name of the tenant. This is included in the URL for the console.
client_id ID of the app
redirect_uri The URI to redirect users to sign in to your app
code_challenge A string based on the code_verifier
code_challenge_method Defines whether the code_challenge is encoded; S256 assigns base64 encoding
state A base64-encoded string
code_verifier A cryptographically random string

5) Substitute those properties in the following URL, and navigate to that URL in the browser of your choice:

content_copy COPY

https://openam-{tenantName}.forgeblocks.com/am/oauth2/realms/root/authorize?grant_type=authorization_code&client_id=<client_id_of_your_native_spa_app>&response_type=code&scope=openid&redirect_uri=https://example.com/homeLogin/&code_challenge=<generated_from_a_code_verifier>&code_challenge_method=S256&state=<arbitrary_string>'

You should be redirected to a screen where you can find the authorization code in the URL, which you can use in the next step:

alt text

6) Use the authorization code and the code verifier to get your access token, ID token, and (with an appropriately configured app) a refresh token:

content_copy COPY

curl -X POST \
  https://openam-{tenantName}.forgeblocks.com/am/oauth2/realms/root/access_token \
  -d 'grant_type=authorization_code' \
  -d 'code=<authorization_code>' \
  -d 'client_id=<native_spa_app_client_id>' \
  -d 'redirect_uri=https://example.com/homeLogin/'
  -d 'code_verifier=<code_verifier>'

If successful, you’ll have appropriate tokens. And you won’t have to risk storing the app client secret on a user browser or device.

PKCE and Web Apps

The process of acquiring access, ID, and refresh tokens using PKCE for web apps is similar to that for Native/SPA apps. The big difference is that because the app isn’t stored on user devices, it’s less risky to include a client secret:

1) Get the SSO token for a user. You can use the same command described in the PKCE and Native/SPA Apps section.

2) Substitute values in the following URL, based on the table shown in the PKCE and Native/SPA Apps:

content_copy COPY

https://openam-{tenantName}.forgeblocks.com/am/oauth2/realms/root/authorize?grant_type=authorization_code&client_id=<client_id_of_your_native_web_app>&response_type=code&scope=openid&redirect_uri=https://example.com/homeLogin/&code_challenge=<generated_from_a_code_verifier>&code_challenge_method=S256&state=<arbitrary_string>'

You should be redirected to a screen where you can sign in to an existing account:

alt text

3) When you sign in, you should see a “code” in the URL, which you can use in the next step:

alt text

4) Use the authorization code and the code verifier to get your access token, ID token, and (with an appropriately configured app) a refresh token:

content_copy COPY

curl -X POST \
  https://openam-{tenantName}.forgeblocks.com/am/oauth2/realms/root/access_token \
  -d 'grant_type=authorization_code' \
  -d 'code={authorization_code}' \
  -d 'client_id={native_web_app_client_id}' \
  -d 'redirect_uri=https://example.com/homeLogin/' \
  -d 'code_verifier={code_verifier}'

In the output, you should now have appropriate tokens.