Notes for WebHooks authentication using JWT, OAuth (with JWT) and OIDC. (Connect 2024)

Since our customers repeatedly requested authentication using OAuth, we have decided to support this scenario. Nevertheless, we would like to clearly point out the following facts at this point: OAuth was not designed to authenticate users or individuals but is a framework for so-called "delegated authorization", i.e. OAuth allows users to share their private resources on one website with another website without having to share their credentials. The OpenID Connect (OIDC) method, also supported by Connect, was developed for authenticating users.

General information on functionality

From the point of view of the called system, a so-called JSON Web Token (JWT) is sent along with the received HTTP request as authentication information. A description of the exact structure of a JWT can be found in RFC7519 described. The task of the recipient (i.e., Connect) is to decode the token and check its validity. Here, checking the validity of the issuer's signature is the most important part of the verification. For this purpose, the public keys of all issuers of JWTs that are to be considered admissible must be disclosed to Connect. This can be done using three different mechanisms, which can also be combined if required:

  1. Direct specification of keys as JSON Web Key Set (JWKS)

  2. Specification of a URI to obtain the current valid keys as a JSON Web Key Set (JWKS)

  3. Determination of the URI under which the current valid keys can be obtained as JSON Web Key Set (JWKS) using OIDC Discovery (OIDC only)

It should be noted here that the issuer of the JWTs usually changes the keys used at regular intervals (automatic key rollover). For this reason, methods 2 and 3 should be preferred, since Connect can react automatically to changes in the signature keys here. The first variant is mostly used for customer developments that do not support automatic key rollover.

After the validity of the signature has been verified, the following checks should be performed:

  1. Is the current system time within the validity period of the JWT? If not, the token is considered expired and therefore invalid.

  2. Is the JWT intended for authentication to the Connect server? When creating the token, the issuer enters the name of the recipient in the Audience field. If this field does not contain the expected value in the received token, it was issued for a purpose other than authentication to the Connect Server and is therefore considered invalid,

  3. Optionally the issuer specified in the JWT can be compared with the values in a list of allowed publishers. If it is not found, the token is considered invalid. If the signing key is known only to the allowed issuers, this check can be omitted. In environments such as Azure AD, where the issuer is responsible for multiple tenants and uses the same signature keys for all tenants, this check can ensure that the access token was not originally intended for another tenant.

  4. Optionally, the used signature algorithm can be compared with the values in a list of allowed signature algorithms. If it is not found, the token is considered invalid. This check prevents the use of undesired signature algorithms.

  5. Optionally, actor token validation can be enabled. A JWT usually contains a field called "sub" (subject) which identifies the user for whom the token was issued. An additional optional field called "actor" contains another JWT and identifies the user acting on behalf of the subject. During actor token validation, this token is also validated (recursively if necessary) according to the configured validation options.

Configuring JWT authentication for webhook calls to a specific service.

To activate authentication via a JWT, the server handler "HttpOAuthHandler" must be specified in the service definition of the corresponding service. For performance reasons, this should be the first server handler, so invalid HTTP requests are rejected before the actual content is processed.

The corresponding server definition then looks like this:

The object named "$params" contains the properties to configure authentication. Currently, the following properties are supported:

Property name

Type

Default value

Description

AllowNonce

boolean

true

In a JWT, a nonce value can be used to associate a client session with an ID token. If an access token is requested via OIDC when using Azure AD contains a scope which is also intended for queries via Microsoft Graph, a string is entered in the JWT as a nonce value. However, the current implementation of the JWT validation of the .NET framework expects the SHA256 hash of this string at this point and thus classifies the signature of the JWT as invalid. If the AllowNonce property is set to true, this activates an early adjustment of the relevant JWTs to prepare it for validation by the .NET framework.

AuthorizationProvider

string

""

If a service that supports OIDC Discovery and is configured as an authorization provider on the Connect Server is used to generate the JWT, the name of the corresponding authorization provider can be entered here. As a result, the valid signature keys are automatically obtained based on the information provided via OIDC-Discovery and key rollovers are also automatically considered during validation.

ClockSkew

TimeSpan

TimeSpan.Zero

This parameter can be used to define the tolerance time span for checking the validity period of a JWT. This enables the compensation of deviating system times. For safety reasons, we strongly recommend not using this parameter and ensuring a functioning synchronization of the system times instead.

JwksData

string

""

Specifies the valid signature keys as JWKS. Please note that the JWKS must be manually adjusted after a key rollover. For this reason, obtaining the signature keys via a URI or via OIDC discovery should be preferred.

JwksUri

string

""

Specifies a URI for obtaining the valid signature keys as JWKS. If the new keys are published directly during a key rollover, this change is automatically considered during validation.

ProxyUri

string

""

If a specific proxy server is to be used to obtain the signature keys via a URI, the URI of the proxy server can be specified here.

ProxyUser

string

""

If a specific proxy server is to be used to obtain the signature keys via a URI and this requires authentication, the user name used for authentication can be specified here.

ProxyPassword

string

""

If a specific proxy server is to be used to obtain the signature keys via a URI and this requires authentication, the password used for authentication can be specified here.

ProxyDomain

string

""

If a specific proxy server is to be used to obtain the signature keys via a URI and this requires the specification of a domain, this can be specified here.

RequireExpirationTime

boolean

true

This parameter specifies that only JWTs containing a validity period are accepted. We recommend not to change the default value.

RequireSignedTokens

boolean

true

This parameter specifies that only JWTs that have been digitally signed by the issuer are accepted. We recommend not to change the default value.

ValidateActor

boolean

true

Activates the validation of the actor token contained in the JWT (recursively if necessary). We recommend not to change the default value.

ValidateIssuerSigningKey

boolean

true

Enables validation of the key used for the signature. We recommend not to change the default value.

ValidateLifetime

boolean

true

Activates the validation of the validity period stored in the JWT. We recommend not changing the default value.

ValidAlgorithms

string[]

[]

Defines a list of allowed signature algorithms and enables validation of the signature algorithm. This validation can prevent the use of undesirable signature algorithms. A list of possible values can be found here: https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms.

ValidAudience

string

""

Contains the expected recipient (audience) stored in the JWT and simultaneously activates the validation of the recipient. This can prevent the use of valid access tokens issued for another purpose.

ValidIssuers

string[]

[]

Defines a list of allowed issuers and enables issuer validation. In environments such as Azure AD, where an issuer is responsible for multiple tenants and uses the same signing keys for all tenants, this validation can ensure that the access token was issued for the expected tenant.