How to configure JWT authentication

Configure IBM® z/OS® Connect to perform authentication by using the claims in a JSON Web Token (JWT) and create the authenticated user from the values of the JWT claims.

Alternatively, you can configure z/OS Connect to:

This task is applicable when using z/OS Connect as an API provider.

Before you begin

Ensure that you have completed the following tasks:
  • You should be familiar with the information in API provider third-party authentication.
  • You must have either an X.509 certificate that contains the public key of the private key that signed the JWT. This key is used to validate the JWT signature. Consult the security administrator of the JWT issuer for how to obtain a suitable X.509 certificate. Or if supported by the JWT issuer, a JWK endpoint URL and the TLS certificates that are required to establish an HTTPS connection to that URL.
  • You need to know the claims that are present in the JWT.
  • You must have write access to the configuration file.

About this task

Configure z/OS Connect to perform JWT authentication. This configuration uses the OpenID Connect Client feature of WebSphere Application Server Liberty Profile to accept the JWT as an authentication token.

This task validates the JWT and creates the authenticated user from the values of the JWT claims, it does not map the JWT to a user registry user.

The authenticated user is created from the value of the JWT claim name that is specified on the userIdentifier attribute of the openidConnectClient server configuration element. The group values associated with the authenticated user subject are obtained from the claim name that is specified on the groupIdentifier attribute of the openIdConnectClient element.

Note: Authentication is not enforced unless authorization roles are defined for the API operations.

The group values associated with the authenticated user subject are compared against the roles that are defined for the API operation being invoked.

This task makes the following assumptions:
  • The JWT is sent to z/OS Connect in an HTTP Authorization request header field as a Bearer token.
  • The RS256 algorithm is used to sign the JWT.
  • The "sub" (Subject) claim in the JWT is the identity to be authenticated.
  • The "accessLevels" custom claim contains the roles that are assigned to the identity for API authorization.
An example of JWT is shown in Figure 1. For a full description of a JWT, see Anatomy of a JWT.
Figure 1. A sample JWT, showing the header, payload, and signature
{ "alg": "RS256" }.
{ "iss": "idg",
  "sub": "SallyKwan",
  "aud": "myentity",
  "exp": 1496230040,
  "iat": 1496229740 }.
  "accessLevels": "Manager" }.
RSASHA256signature....
The following values are used:
  • The header contains an alg (algorithm) with the value RS256, which is the hashing algorithm that was used to sign the JWT. RS256 is RSA Signature with SHA-256.
  • The iss (issuer) claim, idg identifies the principal that issued the JWT. In this example, the JWT was issued by IBM DataPower®, which uses idg as its default issuer value.
  • The sub (subject) claim, SallyKwan is an identity. If the JWT is valid, its signature is verified and other claims such as "aud" and "iss" match the required values then this value will be the authenticated user.
  • The aud (audience) claim, myentity identifies the intended recipient of the JWT. The aud claim is optional. It can be used to identify a specific z/OS Connect or a target API.
  • The exp (expiration time) claim identifies the expiration time on or after which the JWT must not be accepted for processing. This is expressed as a JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds.
  • The iat (issued at) claim identifies the time at which the JWT was issued. This is expressed as a JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds.
  • The accessLevels is a custom claim indicating the access or role that is assigned to the identity. Your environment may use a registered claim, for example scope, or an alternative custom claim for this purpose.
  • The signature (not shown) is calculated by using the header and the payload. The signature certifies that only the party holding the private key is the one that created and signed the JWT, and it also verifies that the claims have not been tampered with.
Note:
  1. If a JWT contains a jti (JWT ID) that is identical to a JWT previously used for authentication with z/OS Connect, the request is considered to be a replay attack. A jti is an optional claim. By default, a subsequent request with the same "jti" claim value will be rejected. To allow multiple requests to use the same "jti" claim value configure tokenReuse="true" on the openidConnectClient configuration element.
  2. If the JWT is issued by a JWT provider that supports JWK (JSON Web Key) or is signed by using the HMAC-SHA256 algorithm, then some steps in this procedure must be modified. For more information, see Alternative configuration when using JWK or the HS256 algorithm.
  3. Only JWS type tokens are supported, not tokens of type JWE.

Procedure

  1. Add the openidConnectClient-1.0 and transportSecurity-1.0 Liberty features to the featureManager element in the configuration file.
    For example,
    <featureManager>
        ...
        <feature>openidConnectClient-1.0</feature>
        <feature>transportSecurity-1.0</feature>
    </featureManager>
  2. Configure the server to use JWT authentication.
    Add the openidConnectClient element to the configuration file. For example:
    <openidConnectClient 
        id="RS"
        audiences="myentity"
        clientId="RS-JWT-ZCEE"
        disableLtpaCookie="true"
        groupIdentifier="accessLevels"
        inboundPropagation="required"
        issuerIdentifier="idg"
        mapIdentityToRegistryUser="false"
        signatureAlgorithm="RS256" 
        trustStoreRef="JWTTrustStore"
        trustAliasName="JWTTrustCert" 
        userIdentifier="sub"
    />
    This element uses the following values:
    • id and clientId are element identifiers.
    • audiences defines a comma-separated list of target audiences. The aud (audience) claim in the JWT must match one of the defined audiences.
    • disableLtpaCookie indicates whether an LTPA token should be created. In this scenario, an LTPA token is not required, so disableLtpaCookie="true" is set.
    • groupIdentifier specifies the name of the JWT claim whose value is stored as the group(s) associated with the authenticated user, and used for authorization checks when invoking an API. This example uses a custom claim name of "accessLevels". The default claim name is groupIds.
    • inboundPropagation is set to required to allow z/OS Connect to use the received JWT as an authentication token.
    • issuerIdentifier defines the expected issuer (iss). This must match the issuer claim value in the JWT. If z/OS Connect receives JWTs with different iss claim values, this value can be a comma-separated list of expected iss values.
    • mapIdentityToRegistryUser indicates whether to map the retrieved identity to a user ID in the user registry. The retrieved identity is the value of the claim that is specified on the userIdentifier attribute. In this example, the userIdentifier attribute is set to "sub" and mapIdentityToRegistryUser="false" so the "sub" value "SallyKwan" will not be looked up in the user registry. If the JWT is valid, its signature is verified and other claims such as "aud" and "iss" match the required values then "SallyKwan" will be the authenticated user.
    • signatureAlgorithm specifies the algorithm to be used to verify the JWT signature. z/OS Connect supports RS256 (asymmetric algorithm) and HS256 (symmetric algorithm).
    • trustStoreRef specifies the name in the id attribute of the keyStore element that defines the location of the validating certificate.
    • trustAliasName is the label or alias of the certificate to be used for signature validation.
    • userIdentifier indicates the claim to use to create the user subject. This identity is then used as the authenticated user ID. The default claim to use for the user subject is the sub claim.
    For more information about other openidConnectClient attributes, see OpenID Connect Client (openidConnectClient) in the WebSphere® Application Server for Liberty documentation.
  3. Configure a truststore that is used to validate the JWT signature.
    Skip this step if you use a JWK endpoint to obtain the JWT signature keys. In this example, a private key is used to sign the JWT, so the X.509 certificate containing the public key must be stored in the z/OS Connect truststore.
    1. Add a keyStore element to the configuration file for the truststore.
      The id attribute value of the keyStore element must match the value that is specified on the trustStoreRef attribute of the openidConnectClient element. The keyStore can be a Java™ KeyStore (JKS) or a RACF® key ring.
      For example, to reference a JKS truststore:
      
      <keyStore id="JWTTrustStore"
          location="${server.config.dir}/resources/security/myTrustStore.jks"
          password="mypassword"
          readOnly="true"
          type="JKS" />
      Or, to reference a RACF truststore:
      <keyStore id="JWTTrustStore"
          fileBased="false"
          location="safkeyring:///myKeyRing"
          password="mypassword"
          readOnly="true"
          type="JCERACFKS" />
      For more information about the keyStore element see Server configuration in the WebSphere Application Server for z/OS Liberty documentation.
    2. Add the X.509 certificate that contains the public key that is required to validate the JWT signature into the truststore as a trusted certificate.
      If you use a RACF key ring, connect the X.509 certificate that contains the public key to the RACF key ring with a usage of CERTAUTH.
  4. Add an SSL configuration element.
    To use the openIdConnectClient element for JWT inbound propagation from z/OS Connect V3.0.53, the configuration file must contain a valid SSL configuration. If the configuration file already contains a valid SSL repertoire element, you can skip this step. Otherwise, configure an SSL repertoire element and associate it with the truststore that is configured in step 3.
    For example,
    <ssl id="JWTSSLConfig"
            keyStoreRef="JWTTrustStore"/>
            trustStoreRef="JWTTrustStore"/>
    
    In this example, both the keyStoreRef and trustStoreRef attributes reference the truststore. A separate keystore is not required to authenticate the JWT, but the keyStoreRef attribute is mandatory and must reference a valid keyStore element.
  5. Optional: If JWT authentication is required only for a subset of requests to z/OS Connect, the openidConnectClient element can include an authFilter subelement that represents conditions that are matched against the HTTP request.
    If an openidConnectClient element is configured, then by default, all requests are authenticated by using that configuration. If authentication filters are defined, then only requests that meet the condition that is defined in the authentication filter will be authenticated by using that element.
    For example, if JWT authentication is required for all requests that contain a Bearer token in the HTTP Authorization header, the following authentication filter can be configured as a subelement of the openidConnectClient element used:
    <authFilter><requestHeader matchType="contains" name="Authorization" value="Bearer "/></authFilter>
    For more information about authentication filters, see Authentication Filter (authFilter) in the WebSphere Application Server for z/OS Liberty documentation.

    For more information about configuring the OpenID Connect Client feature with Liberty z/OS, see Configuring JSON Web Token authentication for OpenID Connect.

Results

A JWT is used to authenticate an API request to z/OS Connect. The identity in the JWT is used for authorization control.

Alternative configuration by using JWK or the HS256 algorithm

If the JWT is issued by a JWT provider that supports JWK (JSON Web Key) or is signed with the HMAC-SHA256 algorithm, then a truststore is not required. However, you must specify different attributes on the openidConnectClient element.

Procedure

  1. If the public key is retrieved from a JWK endpoint, you specify the JWK endpoint URL on the jwkEndpointUrl attribute.
  2. If the JWT is signed by using a shared secret key with the HMAC-SHA256 algorithm, define the shared secret key on the clientSecret attribute.