Written in collaboration with:
santosh.kumar97
Previous Blogs:
- [Blog Series] X.509 certificate-based authentication(mTLS) – Demystified
Upcoming Blogs:
- Communication with services using SAP Destination Service(Java)
- Communicating with services using VCAP environment variables(Java)
Introduction:
This is the second blog in this blog post series. This blog will focus on how to generate a certificate-based service key of service and how we can extract the certificate & key and change the format as per requirements. We will also cover how we can use the generated certificate to fetch the bearer token for authenticating the service endpoints.
Content:
- Creating a service key with certificate credentials
- Updating service bindings to enable certificate-based authorization by default
- Generating certificate and key files from the service key
- Changing the format of the certificate
- Using Postman to fetch JWT token using the generated certificate
1) Generating a service key with certificate credentials
You might have observed that when we create a service key for any SAP-managed services, we generally get the client id and client secret for authentication. We typically use the client id and client secret to generate the JWT token from the OAuth.
By default, most SAP-managed services support x509-based authentication, but during the service key creation, it needs to be explicitly passed in the parameters.
Let’s take archiving service, the most common product service.
- Go to your archiving service instance and create a service key without passing any parameters.
- The service key should look like this:
- To generate a service key with certificate and key, we need to explicitly pass the following parameter:
{
"xsuaa": {
"credential-type": "x509",
"x509": {
"key-length": 2048,
"validity": 7,
"validity-type": "DAYS"
}
}
}
- The generated service key should be like this:
The above scenario showed that although the archiving service supported x509 authentication, the default service key generated client id and client secret. So, let's change that!
2) Updating service bindings to enable certificate-based authorization by default
- Go to the mta.yaml file of your application and update the security configuration where you define your data-archiving service instance. Now the data-archiving service will only support x509 authentication.
- Each certificate has a validity period, and we also need to provide validity to the certificate generated for the above service. The default validity will be set as 7 days.
- The next step is to add validity to the x509 certificate. Go to your application which will be binding to the above service, and add the below config.
- Now, if you again go to the data archiving service and create a service key, it should automatically generate a certificate-based credential.
- If you go to your application which has bound with the archiving service and navigate to the Environment Variables (VCAP_SERVICES), you will see that archiving service has certificate-based credentials instead of client secret credentials.
NOTE: You can choose not to set credential-type during service definition and add only during binding. In this case, different microservices consuming the same service will have the option to choose any of the credential-type supported by the service rather than just x509
Congratulations, now you have the certificate and key to fetch the JWT token from archiving service, but how do you fetch the token?
3) Generating certificate and key files from the service key
Before we create the certificate and key files from the service key, we should know that there are multiple formats(extensions) in which certificate files can be stored. You can refer to more about them
here
Where servicekey.json is the service key for archiving service
- This will generate two files cert.pem and key.pem
Bash Script:
#!/bin/bash
if [ "$1" ]; then
cat $1 | jq --raw-output '.uaa.key' > key.pem
cat $1 | jq --raw-output '.uaa.certificate' > cert.pem
KEY=`cat key.pem`
CERT=`cat cert.pem`
URL=`cat $1 | jq --raw-output '.uaa.certurl'`
CLIENTID=`cat $1 | jq --raw-output '.uaa.clientid'`
if [ "$KEY" = "null" ] || [ "$CERT" = "null" ] || [ "$URL" = "null" ] || [ "$CLIENTID" = "null" ]; then
echo "Missing property. 'key', 'certificate', 'clientid' and 'certurl' have to be present in $1"
exit 1
fi
echo "keys extracted to certificate.pem and key.pem"
echo
echo "curl to obtain a token:"
echo curl --cert cert.pem --key key.pem -XPOST $URL/oauth/token -d "'grant_type=client_credentials&client_id="$CLIENTID"'"
else
echo "usage: $0 <credentials.json>"
fi
4) Changing the format of the certificate
5) Using postman to fetch JWT token using the generated certificate
The token can also be extracted through curl using the below command:
curl --cert-type P12 --cert certificate.p12:root -XPOST https://<oauthurl>/oauth/token -d 'grant_type=client_credentials&client_id=<clientid-in-servicekey-json>'
Using POSTMAN:
- First, we need to add the certificate to the POSTMAN for fetching the token using the certificate.
- Go to settings icon -> settings -> Certificates -> Add certificates
- There are two ways to add a certificate:
- Approach 1: We can add separate cert.pem and key.pem files
- Host: Enter certurl from the service key
CRT file: cert.pem (generated above)
Key file: key.pem (generated above)
- Approach 2: the certificate.p12 file, which is password protected
- Host: Enter certurl from the service key
PFX file: certificate.12 (generated above)
Passphrase: root
- Once the certificate is added, we can send the request to the token endpoint.
- The token URL will be “certurl” appended with /oauth/token
- The POSTMAN's request should look like this:
If all the steps are followed properly, the request should return the JWT token, which can be used to call the archiving service endpoints.
7) Summary:
This blog has covered how to create service keys that support certificate-based authentication. We were able to fetch the JWT bearer token to authenticate the service endpoints using curl and POSTMAN. We have also learnt how to extract the certificate from the service key and convert it to another format.
In the next blog, we will see how to use the SAP Destination service to communicate with different services using X.509 certificate.
Please let us know if you find this content helpful and share any inputs and feedback.