Simple and Flexible OAuth 2.0 REST API Call From A... - SAP Community
Simple and Flexible OAuth 2.0 REST API Call From A... - SAP Community
> Simple and flexible OAuth 2.0 REST API Call from a...
Simple and flexible OAuth 2.0 REST API Call from an ABAP Program (S/4HANA on prem or ECC)
14 Kudos
15,505 Views
Introduction
OAuth 2.0. (short for "Open Authorization", https://oauth.net/2/) is an open standard for authorizations and access delegation, commonly used as
a way for internet users to grant websites or applications access to their information on other websites but without giving them the passwords.
This mechanism is widely used as well to connect to the SAP Cloud APIs in the SAP Business Accelerator Hub (https://api.sap.com/ ) . OAuth
makes also technical connections without user contexts between 2 peers possible. The OAuth client credential flow makes sure that only
authorized clients have access to the offered services.
In this blog I describe how to connect from an ABAP Report to a web resource which requires OAuth 2.0 authorization without a user context. The
calls are made without the need of prior configuration like RFC destinations. Just the URLs of both - the token endpoint as well as the API itself -
are needed giving more flexibility to connect to different sources and to control the flow.
Please note that there is an excellent blog already using an OAuth Configuration approach in an SAP backend.
(https://blogs.sap.com/2020/12/18/configuring-oauth-2.0-and-creating-an-abap-program-that-uses-oauth-... )
I will present 2 running examples from the SAP Business Accelerator Hub .
Overview of the general oAuth 2.0 flow for machine-machine communication (M2M)
oAuth Flow (M2M)
The client (ABAP report in our case) requires access to an API endpoint for a certain functionality. The access is first verified via the token
endpoint based on client id and client secret. In case the access can be granted a token is generated which must be presented to the API
endpoint.
ABAP implementation
To get the token for the API call itself you need to execute an HTTP Post call. To identify the OAuth grant type client_credentials is used. This
requires that beside the grant type the client-secret and the client-id have to be passed as HTTP form fields of the call This information is
provided by the owner of the API during client registration..
The HTTP call is done using the SAP basis class cl_http_client so there is no need to create an RFC destination or any other configuration.
The result of a successful call is a JSON containing the access token and additional information like the validity period.
Here comes code snipped 1 including besides the call to the Token Endpoint the report header and the report parameters as well:
REPORT zs4tf_oauth_call_blog.
START-OF-SELECTION.
PARAMETERS: tokenurl TYPE string LOWER CASE,
clientid TYPE string LOWER CASE,
clientsc TYPE string LOWER CASE,
no_auth AS CHECKBOX,
apiurl TYPE string LOWER CASE OBLIGATORY,
apikey TYPE string LOWER CASE OBLIGATORY,
method TYPE string OBLIGATORY DEFAULT 'GET',
body type string lower case.
IF no_auth NE 'X' .
* 1 POST OAUTH2.0 Call to get Token
cl_http_client=>create_by_url( EXPORTING url = tokenurl ssl_id = 'ANONYM'
IMPORTING client = DATA(lo_http_client_token) ) .
"adding headers with API Key for API Sandbox
lo_http_client_token->propertytype_logon_popup = 0.
lo_http_client_token->request->set_method( 'POST' ).
lo_http_client_token->request->set_header_fields( VALUE #(
( name = 'Accept' value = '*/*' )
( name = 'Content-Type' value = 'application/x-www-form-urlencoded' ) ) ) .
lo_http_client_token->request->set_form_fields( VALUE #(
( name = 'client_id' value = clientid )
( name = 'client_secret' value = clientsc )
( name = 'grant_type' value = 'client_credentials' ) ) ).
*Display result
lo_http_client_token->response->get_status( IMPORTING code = DATA(l_status_code) ).
IF l_status_code = 200.
DATA(rv_response) = lo_http_client_token->response->get_cdata( ) .
ELSE.
DATA lt_fields TYPE tihttpnvp .
lo_http_client_token->response->get_header_fields( CHANGING fields = lt_fields ).
cl_demo_output=>display_data( lt_fields ).
ENDIF.
cl_demo_output=>display_json( rv_response ) .
Once the access token is received the API itself can be called. The access token is placed as Authorization header field with the prefix Bearer.
The rest of the call is API specific such as the used method (GET, POST, …) the additional header fields or any form fields or body content. In the
ABAP report I cover some of these possibilities.
The data is displayed using the cl_demo_output interface.
Code snipped 2 follows with the rest of the implementation:
* 2 GET Call to API (Application Call)
CONCATENATE 'Bearer' ls_token-access_token INTO DATA(ls_access) SEPARATED BY space .
*Display result
lo_http_client_api->response->get_status( IMPORTING code = DATA(l_status_code_api) ).
IF l_status_code_api = 200.
DATA(rv_response_api) = lo_http_client_api->response->get_cdata( ) .
ELSE.
DATA lt_fields_api TYPE tihttpnvp .
lo_http_client_api->response->get_header_fields( CHANGING fields = lt_fields_api ).
cl_demo_output=>display_data( lt_fields_api ).
ENDIF.
cl_demo_output=>display_json( rv_response_api ) .
Examples
In real world use the parameters of the report could look like this:
SAP provides running API try outs, on its website https://api.sap.com. These try-outs need no authentication (step 1 is omitted) and are for test
purposes only. I use them as executable examples for anyone of the report.
Parameter Value
NO_AUTH X
APIURL https://sandbox.api.sap.com/SAPCALM/calm-projects/v1/projects
APIKEY jzSnQuhsY1atvSDxJfeBk1LfWlsE69f0
METHOD GET
The SAP HANA Spatial Service (https://api.sap.com/package/SAPHANASpatialServices/overview ) provides APIs to retrieve location based
information for instance to map an address to its geolocation data.
Conclusion
For distributed applications connectivity based on common security standards like oAuth 2.0 is crucial for stable end to end functionality. Here I
described how to link SAP S/4HANA (or an older ECC system) to a oAuth service like provided in the SAP Business Accelerator Hub
(api.sap.com).
Tags:
OAuth2.0
Comments
For production usage I recommend to also handle the OAuth Token lifetime (expiration time).
It is not good to call Token endpoint before every API resource endpoint call.
Hi Lutz,
The APIkeys come from the services (apis). I noticed that they seem to be equal for many different applications for the entire domain.
The credentials part in the json of the body of the geospatial service are special to this service (dont know their purpose) but are independent
from the oAuth flow iself.
Kind Regards
Lutz