OAuth Authorization with JWT Authorization Requests

OAuth Authorization with JWT Authorization Requests

tutorials

Both OAuth and OpenID Connect give you an opportunity to use Request Objects to initiate a flow. When a request is sent this way, all the parameters which would normally be present in the query string, are encoded in a JWT. You can read more about this technique in the Request Objects article. This tutorial presents the configuration of the Curity Identity Server required to use Request Objects.

Prerequisites

Make sure that you’re running the Curity Identity Server in version 6.3.0 or later. If running a clean instance of the Curity Identity Server, make sure to configure it at least with the basic configuration.

Request Objects with signed JWTs

To enable support for Request Objects, in the admin UI, go to Profiles -> Token Service -> General and select the tab Request Object JWT Support. Enabling this feature allows clients to send Request Objects in the authorization request. You can require clients to use Request Objects through a client setting (see below).

JAR configuration

In this section you can also allow clients to sign Request Objects with an asymmetrical key and limit the algorithms which can be used for signing. You can also add claims which will be required in the Request Object. The Curity Identity Server requires the request to have at least redirect_uri and response_type claims. Other authorization request parameters aren’t required to be present in the request JWT, unless they’re added to the list in the configuration.

aud claim value

If the Request Object contains the aud claim, then it must have the value of the Curity Identity Server’s issuer.

If you want to allow clients to use unsigned JWTs as Request Objects, then the Asymmetrically Signed JWT option must be enabled, and the algorithm none added to the list of allowed algorithms. Remember though that allowing clients to send unsigned JWTs does not protect from request tampering.

Client Configuration

Once the Request Object support is enabled in the system, it can be enabled for concrete clients. To do that, go to Profiles -> Token Service -> Clients and edit the client for which you want to enable JAR support. Scroll down to Client Application Settings and open the Advanced tab. Enable the option Request Object JWT Support.

client configuration

Either a signature verification key must be selected, or the option Allow Unsigned for By-value enabled. The signature verification key is the key that will be used to verify the incoming request JWT’s signature. This can either be a public key or a symmetric secret key. The key can be added in the Facilities -> Crypto -> Signature Verification Keys tab.

By default, if the iss claim is present in the request, it must have the value of the client ID. You can override the value which should be required in the iss claim by entering your own value in the Issuer field.

Requiring PKCE

If you require a client to use Proof-Key for Code Exchange, then PKCE will be enforced even if you don’t require the Request Object to contain code_challenge and code_challenge_method claims. On the other hand, if you require these claims in the Request Object, then PKCE will effectively be required, even if the client has the Require Proof Key option disabled. This is because the Curity Identity Server will expect the token request to contain code_verifier, because the authorization request contained a code_challenge.

By-Reference Request Objects

If you want to allow a client to send By-reference Request Objects (through the request_uri parameter), you can enable the option By reference in the client’s Request Objects settings.

By-Reference client configuration

To properly handle Request Objects sent by reference, an HTTP client must be provided. It will be used to fetch the Request Object. Also, the URL from which the Request Object will be downloaded from, must be whitelisted, in order to avoid any abuses of this mechanism. You can use a wildcard character to allow any URL (*), or you can use the wildcard character at the end of the URL, so that requests can have dynamic paths. For example, if a Request Object would be reachable with the URL https://example.com/request-jwts/GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM, then use the value https://example.com/request-jwts/*.

Test the Flow

You can test the flow using OAuth.tools. Open a new code flow, and toggle the JWT Secured Authorization Request (JAR) option, under the Use PKCE toggle. If you can’t see the toggle, then go to the environment settings and refresh the metadata. OAuth.tools need to get information that your instance of the Curity Identity Server has JAR support enabled. (JAR is not enabled on Curity Playground environment.)

Once you enable JAR, you have to specify the signature algorithm - RS256, and provide a key pair or generate a new one. Click on Generate Key to create a new pair of keys.

Take the generated public key and add it in your Curity Identity Server as a Signature Verification Key, then configure your client to use this key to verify incoming Request Objects.

OAuth.tools configure JAR

Then start the authorization flow by clicking on Run. You can also inspect contents of the request JWT.

client_id in the request

Note that client_id is present in the query string. This is because the OAuth specification requires the parameter client_id to be present in the query string. That parameter can also be included in the Request Object. If it is, then the Curity Identity Server validates if these two values match - the client ID from the query string and from the Request Object.

Request Objects with encrypted JWTs

If you need to protect the privacy of authorization request parameters, then one way is to use encrypted JWTs (JWE) as Request Objects. The Curity Identity Server supports JWE, but to enable a client to use them in an authorization request you will need to edit the configuration using CLI or RESTConf. Currently, it can’t be set using the admin UI.

To enable support for encrypted Request Objects for a client, follow these steps. First, enter the configuration CLI by typing in your shell:

idsh
configure

Next, set these three settings, by typing these commands

set profiles profile token-service oauth-service settings authorization-server request-object encrypted-jwt allowed-algorithms RSA-OAEP
set profiles profile token-service oauth-service settings authorization-server request-object encrypted-jwt allowed-content-encryption-algorithms A256CBC-HS512
set profiles profile token-service oauth-service settings authorization-server request-object encrypted-jwt decryption-key decryptionKeyID

Remember to change the token-service name in path, if your Token Profile has a different name. Set the decryptionKeyID to an ID of a private key used for decryption. This key can be added in the admin UI, in Facilities -> Crypto -> Decryption keys. Adjust the allowed key encryption algorithms and allowed content encryption algorithms accordingly to what will be used by your client.

Commit the changes by calling the commit command and exit the shell. You can now use encrypted JWTs as Request Objects.

The encrypted JWT used as a Request Object should be a nested JWT. This means than in the JWE header there should be a claim cty with value jwt, and the payload of the JWE should be the signed JWT containing the request parameters.

Conclusion

Using signed Request Objects can help you in situations, where request parameters get too large to send them in the query string or where there is a need of guarding the consistency of request parameters. Where you also need to safeguard privacy, Request Objects can additionally be encrypted. These functionalities will prove useful especially in setups which require high levels of security, such as financial-grade APIs. With the Curity Identity Server you can easily implement solutions which use Request Objects.

Keep up with our latest articles and how-tos RSS feeds.