Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Mani_P_S
Product and Topic Expert
Product and Topic Expert

Motivation


Previously, communication from cloud to on-premise via a technical communication user was only possible via basic authentication. Here, I try to cover a new, more secure means to achieve this using OAuth and x.509 certificatesFor more details around basic authentication v/s OAuth, refer the "Introduction to OAuth" section of the blog consuming a business technology platform service from an S/4HANA system using SM59 destination with .... Note: The above blog talks about on-premise to cloud connectivity and therefore other sections may not be relevant in the context of the current blog. 

I use an OAuth client that is being issued by an internet based authorisation server. This client sends the clients' access token into the on-premise network, where the cloud connector transforms it into a client certificate. That way, I do not have to share any credentials of the on-premise system with the cloud environment. Additionally I can use either secret based or mTLS based authentication mechanisms to obtain the access token, where the latter is generally considered more secure than basic authentication. We cover the mTLS based authentication mechanism in this blog.

Learn more here (Authenticating Users against On-Premise Systems | SAP Help Portal).

The following diagram depicts the flow from SAP S/4HANA Cloud, Public Edition.



OAuth with mTLS


For general information on what OAuth with mTLS means, refer https://oauth.net/2/mtls/ and https://datatracker.ietf.org/doc/html/rfc8705 . If you are unaware of how mTLS works, it is recommended to read through the above links before continuing.

Prerequisites



  1. SAP Cloud Connector (see here)

  2. On Premise system configured to trust certificates forwarded by the SAP Cloud Connector (see here)

  3. Subaccount with configured SAP Cloud Connector (see here)

  4. SAP BTP ABAP Environment or SAP S/4HANA Cloud system connected to the subaccount where the cloud connector is configured (see here)

  5. For OAuth with mTLS: A valid certificate uploaded to the ABAP system on SAP BTP ABAP Environment

  6. SOAP/OData service exists in the on-premise system that is ready for consumption


Scenario


Here, I consume an OData service and a SOAP service from an on-premise ABAP system via technical user propagation using OAuth with mTLS (Certificate based authentication). I demonstrate the approach here which is common to both SAP S/4HANA Public Cloud and SAP BTP ABAP Environment.

For OData, we choose the standard product master service available with "/sap/opu/odata/SAP/API_PRODUCT_SRV/". For SOAP, we use a custom SQRT service. However, both of these are just examples and the process should be the same for any other OData/SOAP services.

All steps of the blog would be applicable for both SAP S/4HANA cloud public edition and SAP BTP ABAP Environment unless stated otherwise.

Consume services from the on-premise system


Development - Code based consumption


Persona: Developer in the ABAP system hosted on SAP BTP ABAP Environment or Developer in SAP S/4HANA Public Cloud system (using SAP S/4HANA Cloud ABAP Environment aka Embedded Steampunk)

First set up the code to read data from an on-premise system. Here, I consume the standard product OData service and a custom SOAP service that calculates square root. This blog focuses on the security aspects when consuming services from on-premise systems.

Consumption of OData service


Create a service consumption model to consume the standard product OData service.


Create a new service consumption model object


Choose the Remote Consumption Mode as OData and provide a suitable name, description


Upload the service metadata of the standard product API


Follow through the wizard to have the required objects generated

Create outbound service for Product OData service


The path to the standard Product OData service can be found from the SEGW transaction or the SAP Gateway client in the on-premise system.


On the ABAP system on the SAP BTP ABAP Environment or SAP S/4HANA Cloud, Create an outbound service in ADT with type HTTP and provide the default path prefix as identified above.



Create communication scenario for the Product OData service


Now, we need to expose the service for communication. Here, we create a communication scenario with ADT


Under the outbound tab, add the outbound service created above, ensure OAuth 2.0 is enabled for authentication with grant type "Client Credentials" and publish the communication scenario



Create a class to read product details from the standard OData service


CLASS zcl_product DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

INTERFACES if_oo_adt_classrun .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS ZCL_PRODUCT IMPLEMENTATION.


METHOD if_oo_adt_classrun~main.


DATA:
lt_business_data TYPE TABLE OF za_product,
lo_http_client TYPE REF TO if_web_http_client,
lo_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy,
lo_request TYPE REF TO /iwbep/if_cp_request_read_list,
lo_response TYPE REF TO /iwbep/if_cp_response_read_lst.

TRY.
" Create http client
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_COM_PROD'
comm_system_id = 'S4H_1909_CAL'
service_id = 'Z_PRODUCT_ROOT_REST' ).
lo_http_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
ASSERT lo_http_client IS BOUND.
" If you like to use IF_HTTP_CLIENT you must use the following factory: /IWBEP/CL_CP_CLIENT_PROXY_FACT
lo_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy(
EXPORTING
iv_service_definition_name = 'Z_SCM_PRODUCT'
io_http_client = lo_http_client
iv_relative_service_root = '' ).

" Navigate to the resource and create a request for the read operation
lo_request = lo_client_proxy->create_resource_for_entity_set( 'A_PRODUCT' )->create_request_for_read( ).

lo_request->set_top( 50 )->set_skip( 0 ).

" Execute the request and retrieve the business data
lo_response = lo_request->execute( ).
lo_response->get_business_data( IMPORTING et_business_data = lt_business_data ).

out->write( lt_business_data ).

CATCH /iwbep/cx_cp_remote INTO DATA(lx_remote).
" Handle remote Exception
" It contains details about the problems of your http(s) connection
out->write( lx_remote->get_longtext( ) ).
CATCH /iwbep/cx_gateway INTO DATA(lx_gateway).
" Handle Exception
out->write( lx_gateway->get_longtext( ) ).
CATCH cx_web_http_client_error INTO DATA(lx_web_http_client_error).
" Handle Exception
out->write( lx_web_http_client_error->get_longtext( ) ).
CATCH cx_http_dest_provider_error INTO DATA(lx_destination).
"handle exception
out->write( lx_destination->get_longtext( ) ).
ENDTRY.

ENDMETHOD.
ENDCLASS.

Consumption of SOAP service


Create a service consumption model to consume a custom SQRT SOAP service


Choose the Remote Consumption Mode as Web Service and provide a suitable name/description


Upload the WSDL metadata of the SOAP service


Follow through the wizard to have the required objects generated

Create outbound service for SQRT SOAP service


Identify the request URI for the SOAP service from the SOAMANAGER transaction on the on-premise system


Identify the service interface. This is the proxy class in the service consumption model created for the SOAP service


Create an outbound service using ADT with type SOAP in the ABAP system on the SAP BTP ABAP Environment or SAP S/4HANA Cloud, public edition



Create communication scenario for SQRT SOAP service


Now, we need to expose the service for communication. Here, we create a communication scenario with ADT


Under the outbound tab, add the outbound service created above, ensure OAuth 2.0 is enabled for authentication with grant type "Client Credentials" and publish the communication scenario



Create a class to read the square root of an integer from a custom SOAP service


CLASS zcl_soap_sqrt DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

INTERFACES if_oo_adt_classrun .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS ZCL_SOAP_SQRT IMPLEMENTATION.


METHOD if_oo_adt_classrun~main.

try.
data(destination) = cl_soap_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_COM_SQRT_SOAP'
).
data(proxy) = new zco_z_sqrt_srv(
destination = destination
).
data(request) = value zsqrt_fm( input_num = 4 ).
proxy->zsqrt_fm(
exporting
input = request
importing
output = data(response)
).

out->write( response-result ).

"handle response
catch cx_soap_destination_error INTO DATA(destination_ex).
"handle error
out->write( destination_ex->get_longtext( ) ).
catch cx_ai_system_fault INTO DATA(system_ex).
"handle error
out->write( system_ex->get_longtext( ) ).
catch zcx_zsqrt_fm_exception INTO DATA(fm_ex).
"handle error
out->write( fm_ex->get_longtext( ) ).
endtry.


ENDMETHOD.
ENDCLASS.

Create OAuth Client for Outbound Communication User


Persona: Sub account administrator or space developer on SAP Business Technology Platform

I first need to obtain an OAuth client that is provided by an authorization server. This is trusted by the SAP Cloud Connector (trust established by connecting the Cloud Connector to a sub account).
One way to do so is by creating an instance of the Authorization and Trust Management service in the sub account connected to the Cloud Connector, which results in an OAuth client, which can be used to obtain access tokens. This is done in the sub account connected to the SAP BTP ABAP Environment system or to SAP S/4HANA Cloud



    1. Go to the Marketplace in the Business Technology Platform Cockpit of the sub account




    2. Search for the Authorization and Trust Management Service



    3. Create an instance of service plan application of the Authorization and Trust Management Service (no additional settings are required beyond the first wizard page)




Create Service Key for OAuth with mTLS


Persona: Subaccount administrator or space developer on SAP BTP, administrator on the ABAP system on SAP BTP ABAP Environment/SAP S/4HANA Cloud

To be able to use a client certificate for the OAuth flow, we need to map the certificate of the ABAP system to the OAuth Client (XSUAA instance) we just created.

  1. As an administrator, logon to the Fiori Launchpad of the ABAP system on SAP BTP ABAP Environment or to the Fiori Launchpad of SAP S/4HANA Cloud. Find the app Maintain Client Certificates.

  2. Download the public key in base64 format from the ABAP system
    NOTE: On the SAP BTP ABAP Environment, the default client certificate cannot be used for mTLS since this is self-signed at the time of writing this blog and a valid, signed certificate is needed. On SAP S/4HANA Cloud, it is recommended to use the default client certificate. 

  3. Base64 decode the public key using openSSL. Use any CLI supporting openSSL. I use GitBash in the following screenshots.  

    downloaded.crt is the name of the base-64 encoded certificate downloaded above.



    openssl base64 -d -A -in downloaded.crt -out decoded.crt 



  4. Convert the decoded public key to PEM format using openssl:
    openssl x509 -inform der -in decoded.crt -out public.pem

  5. Put the public key in the generated file "public.pem" into the following json replacing "<public key>". Ensure to adjust the new line characters to resolve errors in the JSON
    {
    "credential-type": "x509",
    "x509": {
    "certificate": "<public key>",
    "certificate-pinning": false
    }
    }​


  6. Use the JSON to create a service key on the XSUAA instance

  7. Keep the resulting service key for later reference


Create a Communication System


Persona: Administrator of the ABAP system hosted on SAP BTP ABAP Environment or Administrator in the SAP S/4HANA Public Cloud system

The Communication System is used to pass the OAuth client details to the ABAP system and to configure how and where the access token should be transported.

  1. Create a new Communication System using the Communication System app.

  2. Configure the on premise system (based on hostname/port in the cloud connector configuration) and enable the cloud connector, providing the location ID.

  3. (Optional) In the "Outbound OAuth 2.0 Client Settings" section set Token Endpoint: <URL from service key>/oauth/token

  4. In case of OAuth w/ mTLS set mTLS Endpoint: <certurl from service key>/oauth/token

  5. Enable "Cloud Conn. Technical User Propagation"


  6. In the "Users for Outbound Communication" section create a new outbound user with authentication method oAuth 2.0 mTLS using the client ID from the service key


  7. Save the Communication System


Create a Communication Arrangement


Persona: Administrator of the ABAP system hosted on SAP BTP ABAP Environment or Administrator in the SAP S/4HANA Public Cloud system

  1. Create a Communication Arrangement for the desired Scenario and use the Communication System we just created

  2. Make sure that the Authentication Method is OAuth 2.0 and the Client ID is the one we just configured


Configure the Subject Pattern in Cloud Connector


Persona: Cloud connector administrator

Documentation: Configure Subject Patterns for Principal Propagation | SAP Help Portal
To define how the OAuth access token shall be handled in the Cloud Connector and how a resulting client certificate should look like, we define a pattern, which is applied to the incoming access token.
In our example we take the client id and put it into the CN of the subject name.

  1. Open the Configuration > OnPremise menu in the Cloud Connector

  2. Scroll down to the Principal Propagation section

  3. Create a new Subject Pattern

    1. Enter a Condition that the ${user_type} is Technical

    2. Enter the CN as ${client_id} to reference the client id of an incoming access token

    3. Provide appropriate values for the other fields



  4. Generate a sample certificate

  5. Enter the client ID from the service key of the XSUAA instance


Map Certificate to an On-Premise Technical User


Persona: Administrator

To be able to authenticate a user with the certificate issued by the Cloud Connector, we map the Subject (OAuth Client ID) and Issuer (Cloud Connector) combination to an actual user in the on premise system.

  1. Open transaction certrule in the on premise system

  2. Go into edit mode

  3. Upload the sample certificate

  4. Create an "Explicit Mapping" for the target technical user

  5. Save and verify the new mapping is created


End to End Test and Validation of technical user propagation


Persona: Developer, Cloud connector administrator, Subaccount administrator/space developer

Run the classes implementing IF_OO_ADT_CLASSRUN that we defined above for the SOAP and OData services in ADT. Notice the output in the console.


To verify this call indeed happened with the technical user, check the most recent requests from cloud to on-premise in the cloud connector under the "Monitor" menu item. Notice the "User" column reflects the client ID


To verify at the on-premise system, use transaction STAD and filter with the technical user configured during the explicit mapping


Notice the calls indeed happened with this technical user


 

 
1 Comment