Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
cancel
Showing results for 
Search instead for 
Did you mean: 
marc_roeder
Product and Topic Expert
Product and Topic Expert

In a previous blog post, we discussed the use of certificates for authenticating clients and servers in general. Now it's time to see how all this theory works in the real world.

In this tutorial, we will see how to call a technical API exposed by an SAP S/4HANA Cloud Public Edition system with certificate-based authentication. In practice, such calls are typically made by a remote system. To keep things simple, we just use an API client and a command-line tool for demonstration.

Note that this text is only about technical connections with communication users (API users), not about business users (UI users). More on communication management in SAP S/4HANA Cloud Public Edition can be found in the official documentation.

To set up certificate-based authentication, we'll have to do some things on the server side and some on the client side. Here's our plan:

  1. create a client certificate
  2. create a "communication user" in SAP S/4HANA Cloud and upload our client certificate for the communication user to be used during authentication of inbound connections
  3. create a "communication system" in the SAP S/4HANA Cloud Public Edition backend
  4. create a "communication arrangement" (the API to be exposed) in SAP S/4HANA Cloud and map the communication system and -user to it
  5. try it out in some client software

Step One: Get a Client Certificate

This tutorial uses command-line tools available in linux (or the Windows Subsystem for Linux) for the required cryptographic operations.

Create the Private Key and Signing Request

The following command creates a new asymmetric key pair. The private key is written to the file key.pem and the public key is written to the key-signing request csr.pem. The key file can optionally be encrypted with a password.
In addition to the public key, the signing request contains the metadata (the subject) we want to have in our certificate.

openssl req -sha256 -newkey rsa:4096 -nodes -keyout key.pem -out csr.pem -subj "/C=<country>/O=<org>/CN=<hostname>"

The signing request will be sent to a certificate authority (CA) which then signs the public key (including metadata) to turn it into a certificate.

The format of the -subj parameter depends on the CA. The CA only signs certificates with particular subjects (remember that by signing, the CA confirms that the subject correctly identifies us or our host). Which subjects are allowed and what validations have to be passed depends on the CA.

Creation of a key pairCreation of a key pair

Result: a private key key.pem and a certificate signing request csr.pem.
Note: key.pem contains our private key. This is a secret and must not be shared with anyone!

Get the Certificate Signed by the CA

To get our public key signed to turn it into a "good" certificate, we take the csr.pem file to our CA (one of the approved ones from SAP Note 2801396) and ask for a signature. How this works depends on the specific CA. Often, there's a web UI where you upload the signing request and provide proof that the subject line identifies you or a machine owned by you.

The format for the certificate should be .pem and include the full chain of certificates. If the CA does not support .pem format including the full chain, we take PKCS#7-format and convert the file in the next step.

Result: a certificate file cert2.pem or certificatePKCS7.p7b.

Convert PKCS#7 Certificate to .pem Format if Needed

To be accepted by SAP S/4HANA Cloud Private Edition, the client certificate needs to include the full signature chain and be in pem format. If our CA only delivered a PKCS#7 file, we convert it like this:

openssl pkcs7 -print_certs -in certificatePKCS7.p7b -out cert2.pem

The resulting file should look like a list of certificates with human-readable headers in between.

Certificate chain in .pem formatCertificate chain in .pem format

Result: the converted certificate file cert2.pem

This is the certificate file we need to pass during authentication. It can also be uploaded to the system to be mapped to a user for identification. That's what we will do now. So, let's head over to configure our SAP S/4HANA Cloud Public Edition system.

Step Two: Create a Communication User and Upload the Certificate

In the system, we first create a communication user and upload our certificate (app "Maintain Communication Users"). For the user mapping, a .pem file is required. In contrast to the actual authentication, it does not matter here, whether the .pem file contains the full chain of certificates or just the client certificate alone.

Creation of communication user, upload of certificateCreation of communication user, upload of certificate

The subject and issuer of the certificate are shown in the UI after upload.

Client certificate in communication user maintenance UIClient certificate in communication user maintenance UI

Step Three: Reference the Communication User in a Communication System

The communication user must then be assigned to a communication system (app "Communication Systems"), so we also create one of those and reference the new user as one for inbound communication.

Communication system with inbound user and certificate authenticationCommunication system with inbound user and certificate authentication

Step Four: Reference Communication System and -User in a Communication Arrangement

Finally, we decide on the API we want to expose (app "Communication Arrangements"). In our example, we'll take the one for change documents of business roles (corresponding communication scenario: SAP_COM_0366). But this is not important – it's the same for all communication scenarios that have an inbound communication channel supporting certificate-based authentication.

We assign the communication system created before and select our user for inbound communication with authentication method "SSL Client Certificate".

Communication Arrangement. Highlighted: system, user, API endpointCommunication Arrangement. Highlighted: system, user, API endpoint

Sep Five: Try it Out

To see that everything worked, we use our client certificate to call the API endpoint (the service URL displayed in the communication arrangement UI). We try this in two clients: the UI-based API client bruno (which is similar to postman) and the command-line client cURL.

Call Using Bruno

In bruno, client certificates are maintained per collection.

We select the certificate file cert2.pem (the one including the full key chain from step one) and the key file key.pem and add it. As "Domain", we take the host name of the system we want to connect to. If we chose to protect the private key by password, that password must be entered here.

Certificate, private key configuration in the bruno API clientCertificate, private key configuration in the bruno API client

Note that we need to give bruno access to our private key key.pem because the client needs to have access to the secret for authentication. But the private key stays with the client and will not be sent to the server.

In case TLS certificate validation is switched on in the global preferences, we might need to additionally upload the server's CA certificate to bruno (see below).

Call Using cURL

The cURL command line looks like this:

curl --request GET --key key.pem --cert cert2.pem --url https://<S4_host>/sap/opu/odata/sap/APS_IAM_API_BROLE_CDOC/BusinessRoleChanges

 A CA certificate for validating the server's certificate can be passed with the --cacert parameter (read on to learn how to get the CA cert). To suppress checking of the server certificate for testing, we can use the --insecure switch.

Do we Trust the Server? How to Get the CA Certificate?

The previous steps assume that the client (bruno or cURL) is able to validate the server's certificate during the TLS handshake. That only works if the client trusts the CA that signed the server certificate. If the client does not use the operating system's certificate store or the server's CA certificate is not in the certificate store, we will need to establish that trust ourselves.

To check if our client trusts the server, we can do an unauthenticated call to see the response:

curl --request GET --url https://<S4_host>/sap/opu/odata/sap/APS_IAM_API_BROLE_CDOC/BusinessRoleChanges

If the result is an http code 401, the TLS handshake worked (the client trusts the server, but the server requests authentication). An http-level error indicates a failed certificate check.

The same test works in bruno. We just need to remove the client certificate from the collection (or create a second collection without certificate) to call unauthenticated.

If the handshake doesn't work, we need to make our client trust the CA root certificate that signed the server certificate (for almost all SAP S/4HANA Cloud Public Edition systems, that's “DigiCert Global Root G2”). This certificate can be downloaded from the CA. The server certificate can also be seen in a web browser (after logging on to the system) where it can be downloaded directly. Here are some screenshots from Firefox as an example:

Steps to get server certificate from Firefox UISteps to get server certificate from Firefox UI

This certificate can then be used in bruno as a "custom CA Certificate" or passed to cURL using the --cacert parameter.

Certificate verification and CA certificate setting in brunoCertificate verification and CA certificate setting in bruno

What we Achieved

When everything worked, we have a client that trusts the CA that signed the server certificate of SAP S/4HANA Cloud Public Edition.
This enables a secure communication channel.

We have a communication user that is mapped to the desired API's communication arrangement. This authorizes the technical user to do calls against the API.

We have a client certificate that is signed by a CA that SAP S/4HANA Cloud trusts.
This enables us to authenticate against SAP S/4HANA Cloud with this certificate.

And we have our client certificate mapped to the communication user.
This enables us to authenticate as this particular communication user and ultimately get data.

The CAs signing the server and client certificates might of course be different ones, so we show them with different names in the final picture of this blog post.

Client and SAP S/4HANA Cloud: trust relationships and verifications during mutual authenticationClient and SAP S/4HANA Cloud: trust relationships and verifications during mutual authentication