Calling an API secured with OAuth 2.0

OAuth 2.0 is an authorization framework that enables a third-party application to request an HTTP service with limited access permission, either on behalf of a resource owner, or on behalf of the third-party client itself.

IBM® z/OS® Connect API requester OAuth 2.0 support can be used when a CICS®, IMS, or z/OS application, calls a RESTful API that requires an OAuth 2.0 access token.

There are four roles in an OAuth 2.0 flow:
Resource owner
An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end user.
In an IBM z/OS Connect API requester scenario, the resource owner might be the user of the CICS, IMS, or z/OS application, or it might be another entity.
Resource server
The server that hosts the protected resources, and accepts and responds to protected resource requests by using access tokens.
In an IBM z/OS Connect API requester scenario, the resource server is the request endpoint for the remote RESTful API.
Client
An application that makes protected resource requests on behalf of the resource owner and with its authorization.
In an IBM z/OS Connect API requester scenario, the client is a combination of the CICS, IMS, or z/OS application, and the IBM z/OS Connect server that calls the RESTful API on behalf of the CICS, IMS, or z/OS application.
Authorization server
The server that issues access tokens to the client after authenticating the resource owner and obtaining authorization.
In an IBM z/OS Connect API requester scenario, the authorization server is called by the IBM z/OS Connect server to retrieve an access token.

OAuth 2.0 access tokens are used to access protected resources. An access token is normally a string that represents an authorization that is issued to the client. The string is usually opaque to the client. However, an access token can also be in the form of a JSON Web Token (JWT).

Access tokens represent specific scopes and durations of access, granted by the resource owner, and enforced by the resource server and authorization server. For example, in an IBM z/OS Connect API requester scenario, the scope can be set by the CICS, IMS, or z/OS application, on behalf of the resource owner. It can give authorization to a particular subset of a resource or to particular actions (for example, read access but not write access). In addition, other parameters such as resource and audience can be used to limit the context in which an access token is valid.

Figure 1. Example OAuth 2.0 flow with IBM z/OS Connect API requester.
Diagram shows an example OAuth 2.0 flow as described in the text.
The steps in Figure 1 show how an API secured with OAuth 2.0 can be called by using IBM z/OS Connect API requester:
  1. The z/OS application passes credentials and other optional parameters to the communication stub.
  2. The communication stub sends the request to the IBM z/OS Connect server.
  3. The IBM z/OS Connect server uses the OAuth 2.0 parameters from the z/OS application and the grant type that is defined in server.xml to construct a request that is sent to the authorization server over a TLS connection.
  4. The authorization server authenticates the client credentials, and verifies other parameters that are included in the request.
  5. If validation is successful, the authorization server returns an access token to the IBM z/OS Connect server.
  6. The access token is sent in the HTTP Authorization header on the request to the RESTful API and it determines the access that is allowed to the resource owners resources.

OAuth 2.0 support by IBM z/OS Connect

IBM z/OS Connect supports the OAuth 2.0 client credentials and resource owner password credentials grant types that are defined in RFC 6749: The OAuth 2.0 Authorization Framework. Using either grant type, there is support for the resource parameter that is defined in RFC 8707: Resource Indicators for OAuth 2.0, and other custom parameters. In addition, JWT authentication with the authorization server can be used instead of authentication with client credentials (basic authentication), as defined in RFC 7523 JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (authorization grants are not supported). JWT authentication avoids the need to securely store one or more client secrets.

Client credentials grant type
This grant type allows the CICS, IMS, or z/OS application, to request a resource on behalf of the resource owner without the resource owners credentials. The client credentials grant type can be used only by confidential clients, so both client ID and client secret are required, unless using JWT authentication, when a client secret is not required.
Resource owner password credentials grant type
This grant type is suitable for z/OS applications capable of obtaining the resource owners credentials (username and password), for example, by using an interactive form. For the resource owner password credentials grant type, client ID is required and client secret is optional. A client secret is required only if the client is defined as confidential, rather than public, in the authorization server, unless using JWT authentication, when a client secret is not required.
Enable this grant type only when the client credentials grant type is not a viable option.

The parameters that can be used for basic authentication are summarized in Table 1 and Table 2, and for JWT authentication in Table 3 and Table 4. Additional parameters that can be set, when using either grant type, to specify restrictions for the OAuth 2.0 access token usage. These are summarized in Table 5.

Table 1. Parameter settings for client credentials grant type with basic authentication
OAuth 2.0 parameter Required COBOL application variable
(For PL/I, see Note 2.)
server.xml (See Note 3.)
grant_type Required value:
”client_credentials"
N/A grantType attribute of zosconnect_oAuthConfig element.
client_id
(See Note 1.)
Required BAQ-OAUTH-CLIENTID user attribute of zosconnect_authData element, referenced by basicAuthRef attribute of zosconnect_authorizationServer element.
client_secret
(See Note 1.)
Required BAQ-OAUTH-CLIENT-SECRET password attribute of zosconnect_authData element, referenced by basicAuthRef attribute of zosconnect_authorizationServer element.
Table 2. Parameter settings for resource owner password credentials grant type with basic authentication
OAuth 2.0 parameter Required COBOL application variable
(For PL/I, see Note 2.)
server.xml (See Note 3.)
grant_type Required value:
”password"
N/A grantType attribute of zosconnect_oAuthConfig element.
client_id
(See Note 1.)
Required BAQ-OAUTH-CLIENTID user attribute of zosconnect_authData element, referenced by basicAuthRef attribute of zosconnect_authorizationServer element.
client_secret
(See Note 1.)
Optional BAQ-OAUTH-CLIENT-SECRET password attribute of zosconnect_authData element, referenced by basicAuthRef attribute of zosconnect_authorizationServer element.
username Required BAQ-OAUTH-USERNAME N/A
password Required BAQ-OAUTH-PASSWORD N/A
Table 3. Parameter settings for client credentials grant type using JWT authentication
OAuth 2.0 parameter Required COBOL application variable
(For PL/I, see Note 2.)
server.xml
grant_type Required value:
”client_credentials"
N/A grantType attribute of zosconnect_oAuthConfig element.
client ID in JWT "sub" claim Required N/A tokenSubject attribute of zosconnect_oAuthTokenConfig element, referenced by jwtAuthenticationTokenRef.
client_id in request body Optional N/A tokenSubject and jwtAuthenticationSetClientId attribute of zosconnect_oAuthConfig element.
client_assertion
(See Note 4.)
Required N/A jwtAuthenticationTokenRef attribute of zosconnect_oAuthConfig element. (See Note 5.)
Table 4. Parameter settings for resource owner password credentials grant type using JWT authentication
OAuth 2.0 parameter Required COBOL application variable
(For PL/I, see Note 2.)
server.xml
grant_type Required value:
”password"
N/A grantType attribute of zosconnect_oAuthConfig element.
client ID in JWT "sub" claim Required N/A tokenSubject attribute of zosconnect_oAuthTokenConfig element, referenced by jwtAuthenticationTokenRef.
client_id in request body Optional N/A tokenSubject and jwtAuthenticationSetClientId attribute of zosconnect_oAuthConfig element.
client_assertion
(See Note 4.)
Required N/A jwtAuthenticationTokenRef attribute of zosconnect_oAuthConfig element. (See Note 5.)
username Required BAQ-OAUTH-USERNAME N/A
password Required BAQ-OAUTH-PASSWORD N/A
Table 5. Additional parameter settings for any grant type
OAuth 2.0 parameter Required COBOL application variable
(For PL/I, see Note 2.)
server.xml (See Note 3.)
scope Optional BAQ-OAUTH-SCOPE-PTR N/A
resource Optional BAQ-OAUTH-RESOURCE-PTR oAuthResource attribute of the applicable zosconnect_apiRequesters > apiRequester subelement.
audience Optional BAQ-OAUTH-AUDIENCE-PTR N/A
<custom parameters> Optional BAQ-OAUTH-CUSTOM-PARMS-PTR N/A
Note:
  1. If both client ID and client secret are required, either they must both be configured in server.xml, or must both be set in the CICS, IMS, or z/OS application.
  2. For PL/I, the variable names have underscore characters in place of the hyphen characters, for example, BAQ_OAUTH_CLIENTID.
  3. Where a value can be specified both in the application and in server.xml, the value in server.xml overrides the application setting, if both are set.
  4. The parameter client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer is automatically added to the request body when using JWT authentication.
  5. The jwtAuthenticationTokenRef attribute of the zosconnect_oAuthConfig element, references a zosconnect_oAuthTokenConfig element, which itself references a jwtBuilder element that defines how to build the JWT.

For more information about developing your CICS, IMS, or z/OS application to use OAuth 2.0, see Developing z/OS applications to call APIs and OAuth 2.0 parameters. For information about configuring the IBM z/OS Connect server for OAuth 2.0, see How to configure OAuth 2.0 with basic authentication and How to configure OAuth 2.0 with JWT authentication.

Signing JWTs

If using JWT authentication, and the tokens are to be signed by using the RS256 algorithm, the key that is used to sign the JWT is available as a JSON Web Key (JWK). To validate the signature, the authorization server can retrieve the key from the JWK API, which has the following format:

https://<host_name>:<ssl_port>/jwt/ibm/api/<jwtBuilder_configuration_id>/jwk
Where:
  • The <host_name> is the hostname of the IBM z/OS Connect server.
  • The <ssl_port> is an HTTPS port that is configured for the IBM z/OS Connect server.
  • The <jwtBuilder_configuration_id> is the ID of the jwtBuilder element.

Using JWK avoids the need to exchange the key that is used to sign the JWT with the authorization server and the problems that are associated with key rotation. However, you can exchange the keys with the authorization server if required in your environment, in this case, use your own key pair to sign the JWT.

To sign JWT with dynamically generated key pairs: set jwtBuilder element jwkEnabled attribute to true. IBM z/OS Connect server dynamically generates key pairs and signs the JWT token with the private key. The private key is available via the JWK API.

To sign JWT with your own key pair: set jwtBuilder element jwkEnabled attribute to false, set keyStoreRef and keyAlias attributes to reference your private keystore and certificate. IBM z/OS Connect server signs the JWT token with the private key specified by the keyAlias attribute. The private key is available via the JWK API.

OAuth 2.0 access token request format

Access token requests are sent to the authorization server by using the HTTP POST method. The request body has the application/x-www-form-urlencoded format and the Content-Type header is set to this value. Unless otherwise specified, parameters are sent to the authorization server in the request body.
Basic authentication
By default, if both a client ID and client secret are specified, they are sent in the HTTP Authorization header on the request to the authorization server. Alternatively, to have the client ID and client secret that is sent to the authorization server in the request body, set the clientSecretInBody attribute to "true" on the zosconnect_oAuthConfig element. If a client ID is specified without a client secret, it is always sent to the authorization server in the request body.
JWT authentication
The JWT generated by the IBM z/OS Connect server is sent to the authorization server in the request body in the client_assertion parameter, together with client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer. By default, the client ID is included only in the JWT subject claim. To have the client ID set in the request body, set the jwtAuthenticationSetClientId attribute to "true" on the zosconnect_oAuthConfig element.

OAuth 2.0 access token caching

The IBM z/OS Connect server stores access tokens in the system cache. An access token is reused when the OAuth 2.0-related information for a request matches exactly that of the original request for which the token was obtained. Expired access tokens are cleared from the system cache periodically. When an access token is retrieved from the cache, if the access token is expired or has less than a one-second lifetime left, a new token is obtained.

Although an access token might be within the expiration period when it is retrieved from the system cache, the token might have expired by the time it is received by the API endpoint. When the API endpoint returns a 401 HTTP response code the WWW_AUTHENTICATE header containing "invalid_token", the IBM z/OS Connect server retries the request by using a new access token that is obtained from the authorization server. If this request fails, the error is returned to the client application.

The token cache can be cleared by using the MVS system MODIFY command, for more details see The MODIFY command.

JWTs generated by IBM z/OS Connect for authentication with an authorization server, are not cached.