Skip to Content
Technical Articles
Author's profile photo Mandy Krimmel

Cloud Integration – Automated Notification for Client Certificates Reaching Expiry

This blog describes how to send automated notifications (after the March-24-2019 update) in case the client certificates in User-to-Certificate Mapping reaching the expiry date. The notification is sent using an integration flow.

Automated Notification for Client Certificates Reaching Expiry

The Certificate-to-User Mapping allows a tenant administrator to maintain the client certificates to be used for inbound authentication and authorization. Details can be found in the blog ‘How to Setup Secure HTTP Inbound Connection with Client Certificates’. Renewal of a client certificate is an important task to be done before expiry, else it will lead to message failure for productive scenarios using this client certificate. The tenant administrator can be notified about those client certificates which are about to expire, so that he can take in-time actions for renewal of the same. He needs to get a new client certificate from the sender system administrator and exchange it in the Certificate-to-User Mapping monitor.

You can model an integration flow to get notifications via mail for entries reaching their expiry. This blog provides the description of the steps to model a scenario triggered via scheduler which checks all entries of the certificate-to-user mapping and sends a mail with information about those entries reaching their expiry.

Scenario Description

To enable the notification, we use the OData APIs for certificate-to-user mapping in an integration flow. These APIs can be consumed via https://<tmnUrl>/api/v1 where <tmn> is the address of the tenant management node. Here we will use the API for the certificate-to-user mapping via https://<tmnUrl>/api/v1/CertificateUserMappings . Note that the ValidUntil option of the API is only available after the March-24-2019 update.

Overall scenario looks like this:

The integration flow is triggered by a timer, fetches the client certificate data via an OData adapter, evaluates the certificate status in a script and send a notification mail if the client certificates are about to expire.

Let’s create the flow.

Create Integration Flow with Timer Start Event and OData Receiver

Create an integration flow with Start Timer Event. Using a Request-Reply step, call the OData APIs to fetch details of the certificate-to-user mapping via an OData receiver channel. Below you find the configuration of the OData receiver channel:

Note, that you need to use Operation Query(Get) and enter CertificateUserMappings as Resource Path.

Use General Splitter to Split the List of Certificate

In a General Splitter step you split the received list of certificate-to-user mappings into single entities. Do the split based on XPath /CertificateUserMappings/CertificateUserMapping:

Read Client Certificate Details into Properties in Content Modifier

In a subsequent Content Modifier step you read all the client certificate-specific details via XPath into properties:

Create the following properties:

  • CertificateValidUntil
    • Type: XPath
    • Data Type: java.lang.Long
    • Value: /CertificateUserMappings/CertificateUserMapping/ValidUntil
  • CertificateUserMappingID
    • Type: XPath
    • Data Type: java.lang.String
    • Value: /CertificateUserMappings/CertificateUserMapping/Id
  • CertificateUser
    • Type: XPath
    • Data Type: java.lang.String
    • Value: CertificateUserMappings/CertificateUserMapping/User

 

Evaluate Client Certificate Expiry Status via Groovy Script

In a Groovy Script we calculate the expiry status of the client certificates. Use the following script code:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.text.SimpleDateFormat;

def Message processData(Message message) {
    // Get Properties
    map = message.getProperties();
    long certExpirydate = map.get("CertificateValidUntil");
    // Calculate Expiry 
    long dateNow = System.currentTimeMillis(); 
    long dateDiff = certExpirydate - dateNow;
    def daysToExpire = TimeUnit.DAYS.convert(dateDiff, TimeUnit.MILLISECONDS); 
    // Set Properties
    Date certExpirydateDate = new Date(certExpirydate); 
    message.setProperty("daysToExpire", daysToExpire);
    message.setProperty("CertExpirydate", certExpirydateDate);
   return message;
}

 

Check Client Certificate Status in Router

In a Router step check the days to expire for the client certificate and route to the mail receiver in case the certificate is about to expire. In my configuration I send the notification for certificates the expire in 10 days or less:

Define Non-XML Expression ${property.daysToExpire} > ’10’ for the branch going to the End event. Default branch is the branch to the Mail receiver which is executed if the client certificate expires in 10 days or less.

Configure Mail Receiver

Now we configure the Mail receiver channel sending out the notification. Configure the mail server and authentication you want to use. In the Mail Attributes define the mail receiver and sender mail address and the Mail Subject and Mail Body:

Subject: Client Certificate Expiry Notification

Mail Body:

Dear Administrator,
one Client Certificate for user ${property.CertificateUser} expires by ${property.CertExpirydate}.
Please contact the Administrator of the sender system to provide a new Client Certificate.

Deploy and Run the Integration Flow

Configure the Timer start event to run the flow every day or any other interval that suits your requirements. Deploy the integration flow.

Now you will get an email as soon as a client certificates in the certificate-to-user mapping is about to expire.

Assigned Tags

      37 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Potnuru Sravan
      Potnuru Sravan

      Thanks for sharing. Will try the same 🙂

      Author's profile photo Hemachandan A S
      Hemachandan A S

      Thanks Mandy Krimmel  for the blog but data type – Long is not working in SAP CPI runtime where content modifier failed to catch this XPath value so passing Null to script and conversion Null to long cause whole iflow to fail so I have changed the Xpath datatype to String and modified your code as below -

      import com.sap.gateway.ip.core.customdev.util.Message;
      import java.util.Date;
      import java.util.concurrent.TimeUnit;
      import java.text.SimpleDateFormat;
      import java.time.*;

      def Message processData(Message message) {

      def body = message.getBody(java.lang.String) as String;

      // Get Properties
      map = message.getProperties();
      def Expirydate = map.get("CertificateValidUntil");

      // Calculate Expiry
      def time = Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSS", Expirydate);
      def certExpiryTime = time.getTime();
      def timeNow = System.currentTimeMillis();
      def timeDiff = certExpiryTime - timeNow;
      long dateDiff = Long.valueOf(timeDiff);
      long daysExpire = TimeUnit.MILLISECONDS.toDays(dateDiff);
      def daysToExpire = String.valueOf(daysExpire);
      def certExpiryDate = Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSS", Expirydate).format("MM/dd/yyyy");

      // Set Properties
      message.setProperty("daysToExpire", daysToExpire);
      message.setProperty("CertExpirydate", certExpiryDate);

      // Log Certificate
      def messageLog = messageLogFactory.getMessageLog(message);
      if(messageLog != null){
      messageLog.addAttachmentAsString("Certificate Details", body, "text/plain");
      }

      return message;
      }

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

       

      Hello

      my flow works with Long without any issue. Could you maybe send me your integration flow getting the error? Or even better, open a ticket on LOD-HCI-PI-RT.

      Best regards,

      Mandy

      Author's profile photo Zameer Ahamad
      Zameer Ahamad

      Hi Hema/Mandy,

       

      Followed the exact setps as decsribed in the blog facing below error, checked if there is any issue of symbols, i don't find.

      javax.script.ScriptException: java.lang.Exception: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'long'. Try 'java.lang.Long' instead@ line 10 in Certificate_Validity.groovy, cause: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'long'. Try 'java.lang.Long' instead

      any adjustments are required in Content Modeler or in Groovy script?

       

      Thanks and Regards

      Zameer Ahamad

       

       

      Author's profile photo Sidharth VR
      Sidharth VR

      Hi Mandy,

      This blog was very descriptive. I made some alterations to the blog and customized the alert as per my design. I also tried to fetch "Message processing Log" using https://<tmnUrl>/api/v1/MessageProcessingLogs . That also worked fine. But, when I try to use https://<tmnUrl>api/v1/MessageProcessingLogErrorInformations , I get an exception saying not Implemented

      Can you please tell me a wokaround that could help me to activate the same ?

       

      Thanks,

      Sidharth VR

      Author's profile photo Ines Ahrens
      Ines Ahrens

      Hi Sidharth,

      Error information can only be retrieved for a single message processing log, either via /MessageProcessingLogs('<MessageGuid>')/ErrorInformation or /MessageProcessingLogErrorInformations('<MessageGuid>'). To retrieve the actual error message you need to append /$value.

      For more information including example requests see SAP API Business Hub and Operations Guide for SAP Cloud Platform Integration .

      Best regards, Ines

      Author's profile photo Rajesh Kumar
      Rajesh Kumar

      Thanks for the above details.

      It would be helpful if this feature can be provided out of the box rather than having to develop an iFlow for this.

       

      Cheers

      Rajesh

       

       

      Author's profile photo Sreenivasa Veldanda
      Sreenivasa Veldanda

      Can someone let me know how to create credentialName for odata channel

       

      What are the parameters I need to maintain in keystore and how do I create

       

      Thanks,

      Sreenivas Veldanda.

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      What does this question have to do with this blog?

      Please refer to the Cloud Integration documentation how to create a secure artifact, this has nothing to do with the keystore.

      BR,

      Mandy

      Author's profile photo Sreenivasa Rao Veldanda
      Sreenivasa Rao Veldanda

      Thanks Mandy. My Actual Question is

       

      I am connecting for Keystore Entries.  But I tried with Basic and Oauth Credentials but I am getting 403 error. Do I need to get any authorization Roles to my Id.

       

      Thanks,

      Sreenivasa Veldanda.

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hello,

      I still do not get the question. How are you connecting for keystore entries? This blog is not for accessing the keystore entries, but for accessing user to certificate mappings.

      For keystore entries there is a dedicated blog: https://blogs.sap.com/2017/12/06/sap-cloud-platform-integration-automated-notification-of-keystore-entries-reaching-expiry/

      The user to be used to get the certificate details needs to have rights to read keystore entries: https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/fda781c59e4b46a390ce5b409f60365e.html.

      Did you provide the access rights to the user you use in the OData channel?

      Best regards,

      Mandy

      Author's profile photo Sreenivasa Rao Veldanda
      Sreenivasa Rao Veldanda

      HI Mandy,

       

      Sorry for confusing you. I tried both usermappings and keystore one.

      But when I am hitting those(UserMapping) URL with Odata channel I am getting 403 forbidden error.

       

      Thanks,

      Sreenivasa Veldanda.

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Did you provide the access rights to the user you use in the OData channel? This user must have the authorization to access security material.

      Did you try to call the URL directly in the browser? Does it work there?

      BR,

      Mandy

      Author's profile photo Sreenivasa Veldanda
      Sreenivasa Veldanda

      Hi Mandy,

      Thanks for the reply.  I used basic auth and I created the basic autentication with my id using Security Material and I am using the same crential name in the communication channel.

      But I am trying to connect the below URL in browser, it is giving below error.

      URL:  https://e12345-tmn.***hana.ondemand.com/api/v1/KeystoreEntries

       

      ERROR:

      <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <code>Forbidden</code>
      <message xml:lang="en"/>
      </error>

      What kind of role I need to ask to admin team.

       

       

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hello,

      forbidden is exactly http 403.

      As already mentioned your used needs to have rights to access the keystore. Please see here: https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/fda781c59e4b46a390ce5b409f60365e.html

      Search for task 'View keystore entries' or 'View certificate-to-user mappings', the following two roles are required:

      IntegrationOperationServer.read

      NodeManager.read

      Please ask the tenant admin to assign this roles.

      Best regards,

      Mandy

      Author's profile photo Swati K
      Swati K

      HI Mandy,

      Thanks for the blog. Can we configure daystoexpire with externalization in route condition?

      Regards,

      Swati

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hello Swati,

      yes, you can externalize routing conditions via the externalize button, e.g.

      Is this what you are looking for?

      BR,

      Mandy

      Author's profile photo Swati K
      Swati K

      Thanks Mandy for a quick reply. I am looking ${property.daysToExpire}>'a' and where 'a' should be configurable. I dont think externalization with whole condition ${property.daysToExpire}>'10' will work.

      Regards,

      Swati

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Yes, this should be possible as well:

      Best regards,

      Mandy

      Author's profile photo Swati K
      Swati K

      Thanks Mandy.

      Author's profile photo Sidharth VR
      Sidharth VR

      Hi Mandy,

      In a similar way, I'm trying to fetch the IntegrationRuntimeArtifacts. I'm using the https://<tmn>/api/v1/IntegrationRuntimeArtifacts('<Iflow_ID>')/ErrorInformation/$value.

      but it doesn't return any response. I'm expecting to get the error information. This works in api business hub sandbox, but not in my client system. any idea ?

      Thanks,

      Sidharth VR

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      I would ask you to open a ticket on LOD-HCI-PI-OP-SRV?

      I cannot answer this remotely.

      Mandy

      Author's profile photo Rajesh Kumar
      Rajesh Kumar

      Hi Mandy,

      I Created One iflow with Mail Receiver Adapter.  I am getting Error like Could not Connect to Host . Here I am attaching the screenshots . Please check the same and give me the solution. I am waiting for your replay. I am using SAP CPI Cloud foundry Trial version.

       

       

       

      Author's profile photo Rajesh Kumar
      Rajesh Kumar

      Hi Mandy,

      Error

      Error

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hi,

      to be honest: this blog post is not for error analysis of issues with misconfiguration in the integration flow. The error above looks like a clear configuration issue of the mail receiver adapter. Couldn't connect to host smtp.gmai.com is quite clear? Shoulnt this be smtp.gmail.com? there is an l missing in your address!

      BR

      Mandy

      Author's profile photo Natalia Rios
      Natalia Rios

      Hi Mandy Krimmel ,

      Since Certificate-to-User Mappings is not available in cloud foundry environment, I guess this iflow would be only valid for Neo CPIs, right?
      I think we can only control the validity of the Keystore objects for CF CPI, correct?. But what about the certificates included in the service key? Is there any way via CPI API to fetch that validity as in this blog example?

      Thank you and thanks for these well detail blog posts. Really helpful for people like me starting in CPI!

      Regards,

      Natalia

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hi Natalia,

      you are correct, this APIs are not available in CF.

      Currently there is no option to get notified about expiry of client certificates maintained in the service key.

      We have plans to offer something in future, but as there are no APIs yet from the platform this is not yet possible. As soon as we have something available I will post this.

      Best regards

      Mandy

      Author's profile photo Jens Schwendemann
      Jens Schwendemann

      Hi Mandy, any updates on this? APIs still not available? If we could only monitoring half the communiction (outbound) then we will probably not invest in this too much

       

      Thx and Cheers

      Jens

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Unfortunately the APIs from platform are still not available in CF, this needs some more time to get developed, sorry.

      Will provide this option as soon as possible, but this will still be only mid to long-term.

      Best regards

      Mandy

      Author's profile photo Jens Schwendemann
      Jens Schwendemann

      Sad to hear but thanks for the update.

      Cheers

      Jens

      Author's profile photo Shubham Srivastava
      Shubham Srivastava

      Hi Mandy,

       

      There is an error which is being thrown while running the script:

      javax.script.ScriptException: java.lang.Exception: java.lang.NullPointerException: Cannot invoke method minus() on null object@ line 31 in script2.groovy, cause: java.lang.NullPointerException: Cannot invoke method minus() on null object.

      I have just copied this code for Groovy Script from here.

       

      Could you please help me in this.

      Your help will highly be appreciated.

       

      Thanks

      Shubham

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Please check that you create the properties (especially CertificateValidUntil) correctly in the content modifier. Especially note capital letters !

      Best regards

      Mandy

      Author's profile photo Dimitri Sannen
      Dimitri Sannen

      Hi Mandy Krimmel ,

      Is there an option available out-of-the-box to get alerts when a certificate is close to expiry?

      I know tenant admins receive an SAP email about the CPI certificate itself, but other certificates are not being alerted without a custom iflow.

      Perhaps in the meantime, there is a native feature available?
      For the moment being, OSS note 2683479 contains the most recent information as far as I know

      Thanks a lot
      Dimitri

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hello,

      currently the only option is to use the described integration flow.

      In future it is planned to also offer the option to use CALM monitoring and alerting for certificate expiry. This is on the roadmap for Q3 this year.

      Best regards

      Mandy

      Author's profile photo Harish Desai
      Harish Desai

      Is this solution valid for cloud foundry as well. As there is no certifiacte to user mapping for cloud foundry, is there any way we can use this solution in cloud foundry tenants.

      Author's profile photo Mandy Krimmel
      Mandy Krimmel
      Blog Post Author

      Hello,

      no, this is only valid for Neo. As you rightly mentioned in CF there is no certificate to user mapping, there the certificate needs to be included in a service key.

      We have plans to also offer an WebUI in Cloud Integration to maintain service instances including client certificates, Together with this we would also plan for APIs that could then be used for the alerting use case as well. But this needs some more time as we currently miss some APIs from platform side for this.

      Best regards

      Mandy

      Author's profile photo Yatanveer Singh
      Yatanveer Singh

      Below 3 needs to be added to access the API:

       

      NodeManager.read
      CertificateUserMappings.Read
      IntegrationOperationServer.read