z/OS Connect

z/OS Connect

z/OS Connect

Truly RESTful APIs to and from your IBM Z mainframe

 View Only

Calling a RESTful API secured with OAuth 2.0

By Will Meyerink posted Tue August 11, 2020 05:17 AM

  

1. Introduction

z/OS Connect Enterprise Edition V3.0.4 introduced OAuth 2.0 support for API Requester. In the previous article Calling a REST API from CICS application, we described how to call an OrderDispatch API from the CICS catalog manager application. In this article we describe how to secure calls to the OrderDispatch API using OAuth 2.0.

2. OAuth flows

We introduced OAuth in a previous article Using OpenID Connect with z/OS Connect EE. Please refer to section 2.1 Background on OAuth 2.0 of this article if you are not familiar with OAuth.

In the previous article, we described the Authorization Code OAuth flow. It is generally considered to be the most secure flow because the end user credentials are hidden to the OAuth client, and because only the OAuth client can request tokens.

In the context of API requester for z/OS applications, there is no interaction with the end user. Normally the end user invokes the z/OS application, and the application requires to call a remote API to process the request. To make the remote API call, the z/OS application does not ask the end user again for his credentials. This is why the OAuth flows supported for API Requester with z/OS Connect EE are restricted to the following flows:

  • Client Credentials
  • Resource Owner Password Credentials

In the Client Credentials flow, the OAuth client application presents Client Id and Client Secret to retrieve an OAuth token. In the Resource Owner Password Credentials flow, the OAuth client application presents a user name and password to retrieve an OAuth token. In both cases, there is no need to ask again the end user for credentials.

3. Example security scenario

We describe an example scenario reusing the OrderDispatch API from the article Calling a RESTful API from a CICS application with some additional OAuth 2.0 security requirements:

  • To call the remote API the application must provide a valid OAuth token (access token)
  • To retrieve an OAuth token, the application must provide:
    • Application credentials (Client ID, Client Secret)
    • Scope(s)

In this example, the flow we use, therefore, is the client credentials flow. Figure 1 shows an outline of the scenario.

Figure 1 Example scenario architecture

As shown in Figure 1:

  • z/OS Connect EE plays the role of the OAuth client.
  • The authorization server token end point is an OAuth provider API in IBM API Connect.
  • And the resource server (or remote API) is also in IBM API Connect.

For further information about how to setup OAuth 2.0 with IBM API Connect, please refer to the tutorial in the IBM API Connect documentation (choose the application flow aka client credentials flow): Tutorial: Securing an API by using OAuth 2.0

The different steps of the scenario are as follows:

  1. The CICS application sends the request through the communication stub to z/OS Connect EE with some additional security information.:
    • Client ID
    • Client Secret
    • Scope

    This information has been retrieved by the developer from the IBM API Connect developer portal when registering the application to use the OrderDispatch API.

  2. z/OS Connect EE is configured to call the OAuth provider to retrieve an OAuth 2 access token. It passes the following information on the request:
    • A Client ID and Client Secret in a HTTP authorization header. The Client ID and Client Secret are passed to z/OS Connect EE from the CICS application.
    • A grant_type with the value client_credentials in the body. This value is configured in the server.xml file.
    • A scope with the value POSTdispatch in the body. This value is passed to z/OS Connect EE from the CICS application.
  3. In response to the call to the OAuth provider, z/OS Connect EE receives an access token in the response body. The response also includes the expires_in field which allows z/OS Connect EE to know how long it can cache the token.
  4. z/OS Connect EE sends the access token in the request to the managed API in the HTTP authorization header as a bearer token.
  5. The managed API checks if the access token is valid, and if the scope(s) matches the resource that is being requested. If so, the managed API propagates the request to the API provider, and sends the response back to z/OS Connect EE.
  6. z/OS Connect EE converts the response message from JSON to binary and returns the message to the CICS application.

Assuming setting up this scenario starting from the article Calling a RESTful API from a CICS application, we don’t need to redeploy any artifact (ARA file or copybooks) for the existing API requester, we just need to change some configurations.

4. Configuring the z/OS Connect EE server

In the z/OS Connect EE server.xml file, the zosconnect_endpointConnection and the ‘ssl id=”client2APIC”’ elements have already been configured.
We need first to add a zosconnect_oAuthConfig element with a reference to it in the zosconnect_endpointConnection element. This tells the server which OAuth flow we want to use, in our case, the client credentials flow.
The second element we need to add, is the zosconnect_authorizationServer element and a reference to it in the zosconnect_oAuthConfig element. This element specifies which authorization we want z/OS Connect EE to call to request the access token.

Example 1 shows how we configure server.xml for our scenario:

<zosconnect_endpointConnection id="orderDispatchAPIOAuthProtected” host=https://apigwDP1.pssc.mop.fr.ibm.com port="443” domainBasePath="/mpl-icc/z-api-mpl/” sslCertsRef="client2APIC" authenticationConfigRef="APICOAuthProvider"/> <zosconnect_oAuthConfig id="APICOAuthProvider” grantType="client_credentials" authServerRef="APICAuthServer"/> <zosconnect_authorizationServer id="APICAuthServer" tokenEndpoint="https://apigwDP1.pssc.mop.fr.ibm.com/mpl-icc/z-api-mpl/orderDispatchOAuthProvider/oauth2/token" sslCertsRef="client2APIC"/> <ssl id="client2APIC" keyStoreRef="APICTrustStore" sslProtocol="TLSv1.2"/>

Example 1 Security elements of the z/OS Connect EE server.xml

5. Modifying up the COBOL code

Firstly, we need to verify BAQ-REQUEST-INFO-COMP-LEVEL variable in the BAQRINFO copybook provided by the z/OS Connect EE build toolkit. The value of this field must be set to 1 as shown below:

03 BAQ-REQUEST-INFO-COMP-LEVEL PIC S9(9) COMP-5 SYNC VALUE 1.

Example 2 BAQRINFO copybook compatibility level

Note: Do not override the value in the code.

Secondly, for the COBOL program that is doing the call to the communication stub we need to populate some fields in the BAQRINFO copybook as follows:

* OAuth 2.0 Client credentials MOVE '' TO BAQ-OAUTH-USERNAME. MOVE 0 TO BAQ-OAUTH-USERNAME-LEN. MOVE '' TO BAQ-OAUTH-PASSWORD. MOVE 0 TO BAQ-OAUTH-PASSWORD-LEN. MOVE '802c0db7-844c-499a-b8a2-d443ad43aa4a' TO BAQ-OAUTH-CLIENTID. MOVE 36 TO BAQ-OAUTH-CLIENTID-LEN. MOVE 'jT2qU7cC1wI5iE5wR2...vA3iA1eS1eY8wW5iB0nK6qB' TO BAQ-OAUTH-CLIENT-SECRET. MOVE 50 TO BAQ-OAUTH-CLIENT-SECRET-LEN. MOVE 'POSTdispatch' TO BAQ-OAUTH-SCOPE. SET BAQ-OAUTH-SCOPE-PTR TO ADDRESS OF BAQ-OAUTH-SCOPE. MOVE 12 TO BAQ-OAUTH-SCOPE-LEN.

Example 3 Client ID, Client Secret and Scope initialization

Note: Client ID and Client Secret can also be configured in the server.xml file using a basicAuthRef attribute in the zosconnect_authorizationServer element.

The next step is to re-compile the COBOL program MOP0XAOD and to re-deploy the program to the CICS server.

6. Testing the Scenario

When we place an order on the EGUI catalog manager transaction, the modified COBOL program now calls the z/OS Connect EE server through the communication stub with additional information: Client ID, Client Secret and scope. The z/OS Connect EE server identifies the OAuth flow as a client credentials flow, so it first calls the authorization server to retrieve the access token, and then calls the resource server (or managed API) passing the token.

Example 4 shows an example of a response from the authorization server:

{ "token_type": "bearer", "access_token": "AAIkODAyYzBkYjctODQ0Yy00OTlhLWI4YTItZDQ0M2FkNDNhYTRhct4GR6Ey5n27zW7z-cRnwTKWC-bXotdN97ylP4j4XPr-Azq8mSlTkn8VBzTt-IWcSmqF4_uvM_RuhZvt9LeWeNLfaD-Zd6YFU2ATy9kRQGd6BKsWLB3qE_Ubz9ysg2BjUClDY0iomblYAQGP0al5Fw", "expires_in": 60, "consented_on": 1520430964, "scope": "POSTdispatch" }

Example 4 Response from the authorization server.

Example 5 shows an example of the header added by z/OS Connect EE server to the request to the resource server:

Authorization: Bearer AAIkODAyYzBkYjctODQ0Yy00OTlhLWI4YTItZDQ0M2FkNDNhYTRhct4GR6Ey5n27zW7z-cRnwTKWC-bXotdN97ylP4j4XPr-Azq8mSlTkn8VBzTt-IWcSmqF4_uvM_RuhZvt9LeWeNLfaD-Zd6YFU2ATy9kRQGd6BKsWLB3qE_Ubz9ysg2BjUClDY0iomblYAQGP0al5Fw

Example 5 HTTP authorization header created by z/OS Connect EE server.

Example 6 shows an example error message in the CICS log if the credentials (Client ID – Client Secret) are not valid.

0055EGUI 20180323170030 Error code: 0000000500 0055EGUI 20180323170030 Error msg:{"errorMessage":"BAQR1082E: An error response is returned from the authorization server. Error: {\"error_description\":\"c 0055EGUI 20180323170030 lient_id unauthorized\",\"error\":\"invalid_client\"}"} 0055EGUI 20180323170030 0055EGUI 20180323170030 0055EGUI 20180323170030 0055EGUI 20180323170030 0055EGUI 20180323170030 0055EGUI 20180323170030 0055EGUI 20180323170030 Error origin:ZCEE

Example 6 CICS log showing an API requester error message when the credentials are not valid

Example 7 shows an example error message in the CICS log if the scope does not match the resource’s scope.

0055EGUI 20180323165341 Error msg:{ "httpCode":"403", "httpMessage":"Forbidden", "moreInformation":"Internal Server Error" } 0055EGUI 20180323165341 0055EGUI 20180323165341 0055EGUI 20180323165341 0055EGUI 20180323165341 0055EGUI 20180323165341 0055EGUI 20180323165341 0055EGUI 20180323165341 0055EGUI 20180323165341 Error origin:API

Example 7 CICS log showing an API requester error message when scope is not valid

7. Caching

In the response from the authorization server, z/OS Connect EE uses the expires_in field in seconds to determine how long to cache the access token. For every new request coming from CICS with the same key:

Token end point URI + Client ID + Scope(s)


z/OS Connect EE does not request a new access token, but instead uses the cached token to directly invoke the managed API.

8. Summary

This example scenario shows how a z/OS application can retrieve an access token to invoke a remote API secured with OAuth 2.0.

The article is one of a series of articles on z/OS Connect EE security written by the IBM Montpellier Client Center team, Aymeric Affouard, Eric Phan and Nigel Williams.
Published on 06/22/2018 / Updated on 06/29/2018

More information on configuring security with z/OS Connect EE can be found in the IBM Knowledge Center.

0 comments
19 views

Permalink