Create a Token Handler

On this page

The Token Handler Design Overview explains how to follow OAuth best practices for browser-based apps while also ensuring the best all-round architecture for your SPAs. You implement the token handler pattern by deploying components to the API side of the architecture:

Token Handler

Curity provides a tested and supported token handler implementation available for purchase. It consists of an OAuth Agent and an OAuth Proxy. You plug them in and do not need to write any code to deal with cookie mechanics:

  • Curity's security experts develop and maintain your web cookie security.
  • The solution works with any OAuth authorization server.
  • You get design guidance and professional services support.
  • SPA developers can follow a code example to upgrade their SPAs to cookie security.

Standards-based Solution

The token handler is a Backend for Frontend (BFF) that can be used with any OAuth authorization server. Your SPA integrates with token handler endpoints using lightweight Ajax requests.

In this tutorial we explain the main integration steps. If you are new to the token handler pattern, you may also want to run the SPA and Token Handler Code Example on your computer to get a feel for how the end-to-end solution works.

Design Token Handler URLs

Since the token handler is a backend for frontend, you must deploy it in the same site as your SPA, so that your SPAs can call APIs without the browser dropping cookies due to third-party cookie restrictions. For the purposes of this tutorial we use the following example URLs:

ComponentBase URL
SPA Web Originhttps://www.product.example
Token Handlerhttps://bff.product.example
Authorization Serverhttps://login.example.com

Other options are supported and we say more about deployment at the end of this tutorial. First though, we explain configuration settings and show you how to get up and running.

Base Setup

First, ensure that you have a license with support for the token handler feature. You can download a trial license from the Curity Developer Portal.

Standalone Token Handler

You can run a standalone token handler if your SPA uses an external authorization server. Do so by following the getting started guides to deploy and configure the system:

Select the option to create a Token Handler only configuration:

Token Handler Configuration

If you switch to Expert mode you can view the base URL that has been generated and update it if required. In the following example the base URL is set to /oauthagent:

OAuth Agent Base URL

Create an Applications Profile

If you use the Curity Identity Server as your authorization server, create an Applications Profile instead. Give it a name such as tokenhandler and a base path such as /oauthagent.

Applications Profile

Create a Token Handler Application

Next, create a token handler application for your SPA. The following screenshot shows a token handler application called example. The OAuth agent for this SPA runs at a path of /oauthagent/example.

Token Handler Application

Once the token handler application is created, click on it to configure its settings for the OAuth Agent and OAuth Proxy.

Configure the OAuth Agent

In the left pane of the admin UI you configure the OAuth Agent. You do this differently depending whether you are using the Curity Identity Server or an external authorization server.

External Authorization Server

If you are using OAuth 2.0 and OpenID Connect with an external authorization server, select the external option and populate settings:

OAuth Agent External Settings

The settings refer to the OAuth client for your SPA at your authorization server and should be familiar to you if you are already using OAuth 2.0 and OpenID Connect:

Client IDThe client ID for the SPA, as registered in your authorization server
Client Secret⃰The client secret for the SPA, as registered in your authorization server
Redirect URIThe redirect URI for your SPA, as registered in your authorization server
Authorization EndpointThe location of your authorization server's authorization endpoint
Token EndpointThe location of your authorization server's token endpoint
Token IssuerThe issuer value your authorization server writes to OAuth tokens that it issues
ScopesThe scopes your SPA uses, as registered in your authorization server
Use PKCEOnly deactivate this if your authorization server does not support Proof Key for Code Exchange (PKCE)
LogoutActivate this to enable RP-initiated logout for your SPA
Logout EndpointThe location of your authorization server's end-session endpoint
Post Logout Redirect URIThe post logout redirect URI for your SPA, as registered in your authorization server

⃰Your SPA is a Confidential Client

Using a backend for frontend (BFF) improves the OAuth security of your SPA. Make sure that you update your authorization server settings so that the SPA is a confidential client that uses a client secret to get tokens.

Internal Authorization Server

If you are using the Curity Identity Server as the authorization server, you use an internal client by referencing an existing OAuth client and entering your SPA's base URL:

OAuth Agent Internal Settings

New Clients

If required, create a new SPA client using the New button and enter basic details. The wizard will then generate all of the correct settings the OAuth Agent needs:

New SPA Client

If you have a license with access to the financial-grade package, activate the Use Financial Grade Security option. Your SPA will then use Pushed Authorization Requests (PAR) and JWT Secured Authorization Response Mode for OAuth 2.0 (JARM) for best protection of browser-level requests.

Existing Clients

If you have an existing client you must edit a couple of settings. First, navigate to Token ServiceClient Settings and enable Symmetrically Signed JWTs:

JWT Authentication

Then, navigate to Token ServiceClients and edit the client settings. Under Client Authentication, ensure that the SPA uses an authentication method of Symmetric Key, and generate one if required. If you have the financial-grade package, also activate the PAR and JARM options.

When tokens are issued for an internal SPA client, the OAuth Agent authenticates at the token endpoint of the Curity Identity Server with a JWT Client Assertion. The OAuth Agent uses the symmetric key to create the JWT and the token endpoint uses the same symmetric key to verify the JWT.

Certificate Trust

In some deployments, the OAuth Agent may call the authorization server over HTTPS using its external URL. In test environments, you might issue your own certificates using a certificate authority that is untrusted by default. In such cases, you must configure the OAuth Agent to use an HTTP client with a trust store.

For example, if using the admin UI, you could navigate to FacilitiesKeys and CryptographyTrust AnchorsClient Trust Stores and import a root certificate. Then, navigate to FacilitiesHTTP Clients and add a client that uses the trust store. Then configure this HTTP client against the OAuth Agent.

HTTP Client

Configure the OAuth Proxy

Next, in the right pane of the admin UI, you prepare your OAuth Proxy. This component enables your SPA to make direct calls to APIs through a high-performance API gateway. The OAuth Proxy runs as an API gateway plugin.

OAuth Proxy Settings

Choose your type of gateway and follow the link to download the plugin from the developer portal, along with configuration and deployment instructions. The following tutorials walk you through the details:

You must configure the OAuth Proxy plugin to execute on all gateway routes from the SPA to APIs. If the SPA calls the OpenID Connect Userinfo endpoint, the OAuth Proxy plugin must also be configured for that route.

Configure Cryptographic Keys

The OAuth Proxy configuration also provides instructions on creating an elliptic curve asymmetric keypair, using the following commands:

openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
openssl ec -in private-key.pem -pubout -out public-key.pem
openssl pkcs8 -topk8 -in private-key.pem -out private-key.pkcs8

Use the Upload button to save the public key to the Curity OAuth Agent, which uses it for encryption. The PKCS8 file is a protected private key that you configure in the OAuth Proxy, to enable it to decrypt the cookie containing the access token, so that it can forward the access token to your APIs.

Cookie Details

The OAuth Agent issues a proxy cookie and a session cookie. The proxy cookie contains the access token for the OAuth Proxy. The OAuth Agent protects this cookie using an ephemeral symmetric key that it derives at runtime from the OAuth Proxy's public key. The OAuth Proxy can derive the same ephemeral symmetric key using its private key and decrypt the proxy cookie.

The session cookie contains the refresh and ID tokens, which are intended for the OAuth Agent. It protects the session cookie with the system's symmetric key. You can locate this key in the admin UI by navigating to SystemZonesSymmetric Key.

Cookie Limits

The token handler uses advanced encryption and compression to reduce cookie sizes. Large JWT access tokens such as those issued by the RS256 algorithm will result in a total cookie size of around 3KB in normal usage, and will not exceed browser or HTTP server limits. For smaller cookies, we recommend using opaque tokens or a more efficient JWT algorithm.

Deploy Token Handler Components

The OAuth Agent is a stateless API that you can cluster. It has no server affinity requirements, so requests during the same OAuth flow can be routed to different instances. You deploy each instance of the OAuth Agent as a docker container or virtual machine. It does not use any data stores, so the component is easy to manage.

One the OAuth Agent is deployed, the SPA can call it by sending HTTP requests of the following form:

curl -i -X POST https://bff.product.example/oauthagent/example/login/start \
-H "origin: https://www.product.example"

You use your cloud platform to provide the external base URL for token handler components. To get you started, we provide a Docker-based Token Handler Deployment Example that you can run on a development computer. It explains all of the settings needed by the SPA, its web static content host, APIs and the OAuth Agent. It gives you clear steps for translating the example environment to your deployed environments.

You can choose between several Token Handler Deployment Patterns. If your API gateway supports routing by host name you could use the same instances of the Curity OAuth Agent to serve multiple SPAs running in different web domains. Alternatively, you can use Service Roles to run distinct OAuth Agents for each web domain.

Integrate Your SPA

Once you have a deployed token handler you can integrate your SPA with it. Your SPA can call the endpoints of the OAuth Agent, which are summarized in the following table:

HTTP MethodEndpoint PathBehavior
GET/sessionThe SPA asks the OAuth Agent for its authentication status and ID token claims
POST/login/startThe SPA asks the OAuth Agent for an authorization request URL
POST/login/endThe SPA asks the OAuth Agent to process an authorization response URL and for its ID token claims
POST/refreshThe SPA asks the OAuth Agent to perform a token refresh and rewrite cookies
POST/logoutThe SPA asks the OAuth Agent to expire all cookies and, when logout is enabled, to return an end session request URL

The SPA using Token Handler code example explains the code integration for SPA developers, covering login, logout, API requests, token refresh, and working with ID token claims and userinfo. The tutorial also focuses on usability control and reliability for your SPAs. We explain how to handle both error and expiry conditions.


The token handler provided by Curity gives you a professional solution, developed by experts, that enables you to upgrade your SPAs to use strong cookie security. This is done in a way that serves your SPAs and externalizes the complexity. You can read more about the token handler in the Admin Guide.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial