
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:
This tutorial uses command-line tools available in linux (or the Windows Subsystem for Linux) for the required cryptographic operations.
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 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!
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.
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 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.
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 certificate
The subject and issuer of the certificate are shown in the UI after upload.
Client certificate in communication user maintenance UI
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 authentication
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 endpoint
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.
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 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).
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.
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 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 bruno
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 authentication
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
5 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 | |
3 | |
2 | |
2 |