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 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. In the case of jku, the server automatically adds the relevant jwk_uri or JWKS to the JOSE array. 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 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. For example, to add the jku header parameter to the JOSE header:

Set JOSE("jku")=""
Set JOSE("jku_local")=%server.Metadata."jwks_uri"
Set JOSE("jku_remote")=%client.Metadata."jwks_uri"
// set JOSE("sigalg") and/or JOSE("encalg") and JOSE("keyalg")
Set sc=##class(%OAuth2.JWT).ObjectToJWT(.JOSE,json,%server.PrivateJWKS,%client.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 Custom Header Parameters

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.

FeedbackOpens in a new tab