Skip to main content

Working with JWT Headers

This topic discusses how to customize the header of a JWT and how to process custom values in a JWT header. Keep in mind that a JWT can be generated by the authorization server or by custom code outside of the OAuth 2.0 framework.

Adding Header Values (Authorization Server)

When the authorization server generates a JWT token, the alg, enc, kid, typ and cty headers are set automatically based on the signature and encryption algorithms used and cannot be directly manipulated with custom code. However, other header values can be added to the JWT header using the JWTHeaderClaimsOpens in a new tab array. For example, JWTHeaderClaims can be used to add jku and jwk header parameters to the token. Note that not all header parameters defined by RFC 7515 are supported. The JWTHeaderClaims array can also be used to add arbitrary custom values to the JWT header.

For example, the following code could be added to a subclass of %OAuth2.Server.ValidateOpens in a new tab to add two standard headers and one custom header value to the JWT header:

ClassMethod ValidateUser(username As %String, password As %String, scope As %ArrayOfDataTypes, properties As %OAuth2.Server.Properties, Output sc As %Status) As %Boolean
  Do properties.SetClaimValue("co","intersystems")

  Do properties.JWTHeaderClaims.SetAt("","jku")
  Do properties.JWTHeaderClaims.SetAt("","co")
  Do properties.JWTHeaderClaims.SetAt("","iss")        

Adding Header Values (Direct JWT Generation)

It is possible to use custom code to generate a JWT outside of the OAuth 2.0 framework using the ObjectToJWT()Opens in a new tab method. This method accepts an array of strings representing the JOSE header as its first parameter. To add values to the JWT header, simply add values to the JOSE array before calling the ObjectToJWT method.

When adding a jku or jwk header, more than one node in the JOSE header is sometimes required. The jku and jwk nodes indicate that these headers should be included, but do not provide the values of these header parameters. For jku, you must also provide the URI to the local, public key using the jku_local node (if signing) and/or the URI to the remote, public key using the jku_remote node (if encrypting).

The jwk node indicates that the JWKS should be included in the header if the JWT is signed or encrypted with an asymmetric algorithm. If the token is signed, the issuer's public JWKS must be included in the JOSE("jwks_local") field. However, the recipient's public JWKS does not need to be specified when encrypting because it is already provided by the RemotePublic argument passed to ObjectToJWT.

For example, to add the jku header parameter to the JOSE header:

Set JOSE("jku")=""
Set JOSE("jku_local")="https://myserver/oauth2/jwks"
Set JOSE("jku_remote")="https://yourserver/oauth2/jwks"
// set JOSE("sigalg") and/or JOSE("encalg") and JOSE("keyalg")
Set sc=##class(%OAuth2.JWT).ObjectToJWT(.JOSE,json,PrivateJWKS,RemotePublicJWKS,.JWT)

For a description of JOSE array nodes that correspond to standard header parameters, see the class referenceOpens in a new tab.

Adding Custom Header Parameters

The JOSE array passed to the ObjectToJWT method can include custom header parameters that are inserted into the JWT header. To include custom header parameters, first define them as key-value pairs in a dynamic object, where the key is the name of the custom parameter and the value is the parameter's value. Once the dynamic object is defined, add it to a node of the JOSE array using the custom subscript. For example, the following code inserts two custom parameters, co and prod, into the JWT header:

Set newParams={"co":"intersystems","prod":"bazbar"}
Set JOSE("custom")=newParams
// set JOSE("sigalg") and/or JOSE("encalg") and JOSE("keyalg")
Set sc=##class(%OAuth2.JWT).ObjectToJWT(.JOSE,json,%server.PrivateJWKS,%client.RemotePublicJWKS,.JWT)

The custom node of the JOSE array cannot be used to override the header values defined by RFC 7515Opens in a new tab. If doing nested signing and encryption, the custom headers will only be included in the "inner" (signed) token.

Processing JWT Headers

The JWTToObjectOpens in a new tab method allows you to process a JWT to return its headers. These headers can be accessed in two ways. Standard JOSE header parameters containing the algorithms used for Signature and/or Encryption operations performed on the JWT are returned by the method in an array of strings. In addition, the "raw" header of the JWT is returned as a dynamic object in the 6th parameter. By parsing the key-value pairs of this dynamic object, you can process custom and standard header parameters that are present in the JWT header. If the token was created using nested signing and encryption, the raw header returned by the method is from the "inner" (signed) token.

Note that the jku and jwk header parameters are not processed by InterSystems IRIS to validate a token that it has received. That is, when calling JWTToObject(), the code needs to supply the local, private JWKS and/or remote, public JWKS using the appropriate arguments.

FeedbackOpens in a new tab