Skip to Content
Product Information
Author's profile photo Harinder Singh Batra

Use OAuth-based Authentication for SAP Conversational AI chatbots

Hi SAP Community,

 

I’m Harinder, and I’m working as a Product Owner at the SAP Conversational AI team. Before going through the detail on how to use OAuth-based Authentication for SAP Conversational AI chatbots, let’s clarify what OAuth is:

 

What is OAuth?

According to the OAuth website, OAuth is the industry-standard protocol for authorization. OAuth focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.
SAP Conversational AI provides public APIs that can be consumed by bot developers to:

  • Configure their bots with design time APIs
  • Interact with their bots with run time APIs using a middleware

With the introduction of OAuth for SAP Conversational AI chatbots in October 2020, bot developers have an option to authenticate the API calls made by their middleware or clients to bots created before February 2021 release of SAP Conversational AI using one of the following methods:

  • OAuth tokens (recommended method)
  • Bot (developer / request) tokens

 

Note: As of May 2023 release, API calls to all the bots (including the ones created before February 2021) will require OAuth tokens to be passed along with the bot tokens. 

 

Depending on the token chosen, you are allowed to make different requests:

  • With your request token (version/environment), you can make requests in the RUNTIME API, to analyze text or start a conversation. When you create a new bot, by default, your bot has only one main version v1 and is assigned to the “DEVELOPMENT” environment. You will have one request token for each version and for each environment of your bot.
  • With your developer token, you can make requests on every endpoint our API provides.

In this tutorial, we will walk you through the steps for calling SAP Conversational AI APIs using OAuth tokens:

Option 1: Generating OAuth token using Client Credentials

  • Step 1: Generate OAuth client for design time/run time APIs
  • Step 2: Generate OAuth token using Client Credentials
  • Step 3: Call SAP Conversational AI APIs using OAuth token

Option 2: Generate OAuth Token using Client Certificate

  • Step 1: Generate OAuth client for design time/run time APIs
  • Step 2: Generate OAuth token using Client Certificate
  • Step 3: Call SAP Conversational AI APIs using OAuth token

Why you should use oAuth-based Authentication for SAP Conversational AI chatbots instead of using Bot tokens

The following table shows the differences between OAuth and Bot tokens and the advantages of using OAuth tokens:

OAuth token Developer / Request token
Token automatically expires after twelve hours and needs to be regenerated every twelve hours Token once generated remains the same throughout the lifetime of a bot and regeneration of the token has to be triggered manually
More secure Less secure
Need to regenerate new token every 12 hours Must update token in middleware every time a new token is generated
No need to update credentials in the middleware every time a new token is generated Need to update token in middleware every time regeneration happens
Certificate based token generation is useful for server to server communication No certificate-based token generation possible

Difference between APIs and authentication

SAP Conversational AI provides two types of APIs:

Design-time Run-time
APIs used to configure the bot (e.g. /entities, /intents, /dataset…) APIs used to interact with the bot (e.g. /dialog or /request…)
Works with developer token of the bot Works with request, version or environment token of the bot

How to use OAuth-based Authentication for SAP Conversational AI chatbots

You can either follow the steps in the video or described below:

Option 1: Generating OAuth token using Client Credentials

Step 1: Generate OAuth client for design time/run time APIs

Go to your Bot Settings and click Tokens.

 

Click the Generate button under the Run time APIs or Design time APIs.

 

Choose Client Credentials and click Next.

 

Once the client is generated, the following fields are displayed:

Field Usage for Token Generation
Auth URL URL to be used for generation of OAuth token
Client ID Identifier of the OAuth client, to be passed in client_id field in request body
Client Secret Secret for OAuth Client to be passed in client_secret field in request body

Step 2: Generate OAuth token using Client Credentials

curl -X POST <Auth_URL> -d ‘grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>’

Note: OAuth tokens expire after twelve hours. The value for expires_in field indicates the time (in seconds).

Step 3: Call SAP Conversational AI APIs using OAuth token

Design time APIs
Headers:

  • Authorization: Bearer <Designtime_OAuth_Token>
  • X-Token: Token <Developer_Token>

Run time APIs
Headers:

  • Authorization: Bearer <Runtime_OAuth_Token>
  • X-Token: Token <Request_Token>

Option 2: Generating OAuth token using Client Certificate

Step 1: Generate OAuth client for design time/run time APIs

Go to your Bot Settings and click Tokens.

 

Click the Generate button under the Run time APIs or Design time APIs.

 

Choose Client Certificate and click Next.

 

Paste the certificate code in the text box and click Generate.

 

Once the client is generated, the following fields are displayed:

Field Usage for Token Generation
Auth URL URL to generate OAuth token
Client ID Identifier of the OAuth client to be passed in client_id field in request body

Step 2: Generate OAuth Token using Client Certificate

curl –cert cert.pem –key key.pem -X POST <Auth_URL> -d ‘grant_type=client_x509&client_id=<client_id>’

Here cert.pem is the public key certificate and key.pem is the private key of the certificate.

Note: OAuth tokens expire after twelve hours. The value for expires_in field indicates the time (in seconds).

Step 3: Call SAP Conversational AI APIs using OAuth Token

To call an API, you need to paste the token in the Headers of the API call.

Design time APIs
Headers:

  • Authorization: Bearer <Designtime_OAuth_Token>
  • X-Token: Token <Developer_Token>

Run time APIs
Headers:

  • Authorization: Bearer <Runtime_OAuth_Token>
  • X-Token: Token <Request_Token>

 

Note: If you don’t need the OAuth token anymore, it is recommended that you delete the token to avoid any security issues.

Congrats, you know how to generate OAuth tokens using Client Credentials and Client Certificate, allowing you to integrate various middleware with your chatbots to interact in a secure and robust manner.

Assigned Tags

      36 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Sagar Salyan
      Sagar Salyan

      How to perform

      Step 2: Generate OAuth token using Client Credentials

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Sagar Salyan ,

      You can refer to "Option 1: Generating OAuth token using Client Credentials" in the blog above.

      Author's profile photo Sagar Salyan
      Sagar Salyan

      I have generated it, how can i integrate this with SAPUI5 app ?

      Author's profile photo Sagar Salyan
      Sagar Salyan

      Also I need to know what is the difference between Runtime APIs and Designtime APIs ?

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Sagar Salyan The difference in Runtime APIs and Designtime APIs is mentioned in the blog above.

       

      Design-time Run-time
      APIs used to configure the bot (e.g. /entities, /intents, /dataset…) APIs used to interact with the bot (e.g. /dialog or /request…)
      Works with developer token of the bot Works with request, version or environment token of the bot
      Author's profile photo Sagar Salyan
      Sagar Salyan

      Thanks

      Author's profile photo Sagar Salyan
      Sagar Salyan

      Please post solution for other queries.

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      I have added replies from my end.

      Please feel free to ask your queries if you still have them.

      Author's profile photo Sagar Salyan
      Sagar Salyan

      Thank you for the solution. Need to check

      Author's profile photo Sagar Salyan
      Sagar Salyan

      This is my UI5 code, here I am getting 'Unauthorized' error.

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Sagar Salyan

      Step 1: Generate the oAuth token by marking the API calls similar to below curl from your UI5 code

       

      curl -X POST <Auth_URL> -d 'grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>'

       

      Step 2: Pass the OAuth token retuned as response of Step 1 to the SAP Conversational AI's API calls in headers mentioned below:

      For Designtime API calls:

      
      Authorization: Bearer <Designtime_OAuth_Token>
      X-Token: Token <Developer_Token>

      For Runtime API calls:

      Authorization: Bearer <Runtime_OAuth_Token>
      X-Token: Token <Request_Token>
      Author's profile photo Nitin Saxena
      Nitin Saxena

      Hi Sagar,

       

      Are you able to connect the conversational AI using Request Token , i am getting 401 unauthorized Like you while using request token .

      Can you please share the details if you have integrated the Bot using oauth token ?

       

       

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Nitin Saxena ,

      Can you please share the code snippet that you are using ?

      Author's profile photo Sathianarayanan Hari
      Sathianarayanan Hari

      The content-type of your request body must be application/x-www-form-urlencoded. You get unauthorised if any other content-type is used.

      Author's profile photo Sagar Salyan
      Sagar Salyan

      Hi Nitin,

      I was facing the same issue, but I resolved it now.

      Thanks to Harinder Singh Batra Ji.

      Please refer to this linked in post. I have uploaded a document for integrating in UI5 app.

       

      https://www.linkedin.com/posts/sagarsalyan_sap-conversational-ai-activity-6801152147523293184-R7_6

      Author's profile photo Nitin Saxena
      Nitin Saxena

      Hi Harinder ,

       

      I am not able to generate Oauth Token , i have generated a Client_id and client_secret in conversational AI , but not able to generate access_token can you tell me the platform through which i can generate access token as if now i am using online bash editor and getting error in generating token , as of now i have written the same code which sagar has mentioned above using developer token .

       

       

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Sample Python Snippet for calling /dialog API:

      import requests
      import json
      
      # Step 1: Call to generate OAuth token
      
      #OAuth - Auth URL
      oAuthURL = ''
      
      oAuthPayload = {
          "client_id": "",
          "client_secret": "",
          "grant_type": "client_credentials"
      }
      
      oAuthHeaders = {
          "Content-Type": "application/x-www-form-urlencoded"
      }
      
      oAuthResponse = requests.post(oAuthURL, data=oAuthPayload, headers=oAuthHeaders)
      oAuthResponseJSON =  oAuthResponse.json()
      oAuthToken = oAuthResponseJSON['access_token']
      
      # Step 2: Call /dialog API
      
      dialogURL = 'https://api.cai.tools.sap/build/v1/dialog'
      dialogPayload = {"message":{"type":"text","content":"hi"},"conversation_id":"test"}
      botToken = ''
      
      dialogHeaders = {
          "Authorization": "Bearer " + oAuthToken,
          "X-Token" : "Token " + botToken,
          "Content-Type" : "application/json"
      }
      
      dialogResponse = requests.post(dialogURL, data=json.dumps(dialogPayload), headers=dialogHeaders)
      print(dialogResponse.json())
      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Sample Java Code for calling /dialog API:

      import java.net.URI;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpRequest.BodyPublishers;
      import java.net.http.HttpResponse;
      import java.net.http.HttpResponse.BodyHandlers;
      import java.util.HashMap;
      import java.util.Map;
      import java.util.Map.Entry;
      
      import com.fasterxml.jackson.databind.JsonNode;
      import com.fasterxml.jackson.databind.ObjectMapper;
      
      public class OAuthSampleJava {
      
          public static void main(String[] args) throws Exception {
              OAuthSampleJava oauthSampleJava = new OAuthSampleJava();
              System.out.println(oauthSampleJava.callDialog());
          }
      
          private String getOAuthResponse() throws Exception {
      
              // OAuth - Auth URL
              String url = "";
      
              // OAuth - Client ID
              String client_id = "";
      
              // OAuth - Client Secret
              String client_secret = "";
      
              Map<String, String> headers = new HashMap<>();
              headers.put("Content-Type", "application/x-www-form-urlencoded");
              String body = new StringBuilder().append("grant_type=client_credentials&client_id=").append(client_id)
                      .append("&client_secret=").append(client_secret).toString();
      
              return sendPost(url, headers, body);
          }
      
          private String callDialog() throws Exception {
      
              // Fetch OAuth token of a bot using client credentials flow
              String oAuthToken = getOAuthToken();
      
              // Should be either community tenant API endpoint i.e. https://api.cai.tool.sap
              // or <tenant_url>/public/api
              String url = "";
      
              // Version or Environment token of a bot
              String botToken = "";
      
              Map<String, String> headers = new HashMap<>();
              // headers.put("Content-Type", "application/x-www-form-urlencoded");
              headers.put("Authorization", "Bearer " + oAuthToken);
              headers.put("X-Token", "Token " + botToken);
      
              String dialogRequest = "{\"message\":{\"type\":\"text\",\"content\":\"Hi\"},\"conversation_id\":\"test\"";
              return sendPost(url, headers, dialogRequest);
          }
      
          private String getOAuthToken() throws Exception {
              String oAuthResponse = getOAuthResponse();
              if (!oAuthResponse.isBlank()) {
      
                  ObjectMapper objectMapper = new ObjectMapper();
                  JsonNode oAuthJSONResponse = objectMapper.readTree(oAuthResponse);
                  return oAuthJSONResponse.get("access_token").asText();
              } else {
                  throw new Exception("Invalid OAuth response");
              }
          }
      
          private String sendPost(String url, Map<String, String> headers, String body) throws Exception {
              HttpRequest.Builder requestBuilder = HttpRequest.newBuilder().uri(URI.create(url))
                      .POST(BodyPublishers.ofString(body));
      
              for (Entry<String, String> header : headers.entrySet()) {
                  requestBuilder.header(header.getKey(), header.getValue());
              }
      
              HttpRequest request = requestBuilder.build();
              HttpClient client = HttpClient.newHttpClient();
              HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
      
              return response.body();
          }
      }
      Author's profile photo Alvaro Achin
      Alvaro Achin

      Hi Harinder Singh Batra , can you help me with the code to call /dialog API in NodeJS?

      I have created a function to get the oauth token, how can I pass this token and the developer token to the dialog?

      bot.dialog('/', async function (session) {    
          var sapcaiToken = await sapcaiToken();
      
          var sapcaiBuild = new sapcai.build(sapcaiToken, 'es'); //Here is my problem
      
          sapcaiBuild.dialog({type: 'text', content: session.message.text},
                             {conversationId: session.message.address.conversation.id},
                             {mail:'anymail@outlook.com',name:'My Name'})
          .then(res => {
              session.send(res.messages[0].content);
          })
          .catch((err) => session.send('Error en conexión a **SAPCAI**: ' + err)); 
      });

      This is the function to get the oauth token, this function is OK.

      async function sapcaiToken(){
          const host_url = 'https://sapcai-community.authentication.eu10.hana.ondemand.com/oauth/token'
          const params = new URLSearchParams();
      
          params.append('grant_type', 'client_credentials');
          params.append('client_id', config.sapcai_clientid);
          params.append('client_secret', config.sapcai_secret);
      
          const result = await nodefetch (host_url,{
              method: 'POST',
              body:    params,
              headers: { 'Content-Type': 'application/x-www-form-urlencoded'}
          });
      
          var output = await result.json();
          output = output.token_type+' '+output.access_token;
          return output;
      }

       

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Alvaro Achin,

      Are you using https://github.com/SAPConversationalAI/SDK-NodeJS ?

      Author's profile photo Alvaro Achin
      Alvaro Achin

      Yes, thanks for your attention. Finally I could solve that.

          const resultDialog = await nodefetch ('https://api.cai.tools.sap/build/v1/dialog',{
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json', 
                  'Authorization': 'Bearer ' + sapcaiOauthToken, 
                  'X-Token': 'Token ' + config.sapcai_request_token
              },
              body: JSON.stringify(bodyJSON)
          })
          .then(res => res.json())
          .then(json => {return json.results.messages[0].content})
          .catch(err => {return err});
      
          session.send(resultDialog);
      
      Author's profile photo Leila Benhariz
      Leila Benhariz

      Hi there,

      I am using the curl command line where I substitute in my URL and the client credentials but I only get the response {"error":"unauthorized","error_description":"Bad credentials"}. This is on Windows 10. Would you have any advice on why I am always getting this error?

      Thanks.

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Leila Benhariz ,

      Are you getting an error message similar to one below ?

      OAuth%20Windows%20Issue

       

      If yes, then execute the curl command by replacing the single quotes the command with double quotes.

      curl -X POST <auth_url> -d "grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>"
      

       

      Reason: Windows terminals accepts double quotes whereas Mac Terminals accepts single quotes in Curl command

      OAuth Windows Issue

      Author's profile photo Leila Benhariz
      Leila Benhariz

      Hi,

      Thanks for replying. I tried that new code snippet but I am still having the same error.

      As far as I can tell, I am putting the tokens in correctly.

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Leila Benhariz ,

      You can try below command and it should work

      curl -X POST '<auth_url>' --data-urlencode 'client_id=<client_id>' --data-urlencode 'client_secret=<client_secret>' --data-urlencode 'grant_type=client_credentials'

      As per https://curl.se/docs/manpage.html#-d the curl command with -d should also work the same way.

      Author's profile photo Leila Benhariz
      Leila Benhariz

      Hi Harinder,

      That worked for getting the access token, thank you so much!

      Just to note for anyone else who may encounter this issue, don't forget to use the double quotation marks on Windows 10.

      curl -X POST "<auth_url>" --data-urlencode "client_id=<client_id>" --data-urlencode "client_secret=<client_secret>" --data-urlencode "grant_type=client_credentials"

      Thanks again, really appreciate it!

      Leila

      Author's profile photo Nitin Saxena
      Nitin Saxena

      Hi Harinder ,

       

      thank you very much for your answer , i have integrated the OData with the Bot with ODATA provisioning and able to read the service from S/4 HANA , but my next doubt is i want to send Json payload  in Post call in conversational AI to create the data in backend , where do we have option to create the payload in Conversational AI ?

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Nitin Saxena ,

      Can you please post this query in SAP Answers and add tag for SAP Conversational AI  and it can be answered by our experts in this area ?

      Author's profile photo Natarajan Narayanaswami
      Natarajan Narayanaswami

      Hi Harinder,

      Is it possible to do SSO when using oAuth integration?

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Natarajan Narayanaswami ,

      if I understood your question correctly,

      it is not possible to do SSO for your chat bot's backend systems using the oAuth token mentioned above as the OAuth tokens mentioned above are only technical representation of your bot and not the user using / interacting with your chatbot.

       

      For end user SSO, please use Webclient with SSO integration.

      Author's profile photo Natarajan Narayanaswami
      Natarajan Narayanaswami

      Hi Harinder ,

      Thanks for reply, let us think we have a bot which we done sso where our bot is integrated to sap fiori launchpad as a plugin using webclient API option. If we migrate to oAuth based authentication, then we will lost SSO right.

      Author's profile photo Aliou NIANG
      Aliou NIANG

      Hello,

      We are using Log API (https://api.cai.tools.sap/logs/v2/conversations/{{conversation_id}} and not dialog one (/build/v1/dialog). Are we concerned by this update ?

      Thank you for your reply

      Author's profile photo Harinder Singh Batra
      Harinder Singh Batra
      Blog Post Author

      Hi Aliou NIANG ,

       

      Yes, all of our public endpoints will be protected with OAuth authentication.
      Please implement the OAuth token mechanism for your implementation / services.

       

      Regards,
      Harinder

      Author's profile photo Pawan Kalyan
      Pawan Kalyan

      Hi Harinder Singh Batra ,

      Thanks a lot for the info...!!!

       

      I would like to understand what is best way to handle Client ID and Client Password in SAP UI5 Application?

      I guess, in different environments we would be having different oAuth Client ID and Password.Besides that we cannot hard code these details. Should we use Destinations Service?

      More over, If you can help me understand how to handle oAuth Token Expiry will be very useful.

      Author's profile photo Tobias Hainke
      Tobias Hainke

      Hi Harinder Singh Batra,

      at the moment we are using a CAI Chatbot which is already running.

      But to be honest i don't understand/know where to run the commands described in these chapters:

      Step 2: Generate OAuth token using Client Credentials
      Step 3: Call SAP Conversational AI APIs using OAuth token

      Step 1 is clear for me.

      But what do i have to change in my application after Step 1 is done?

      At the moment we are consuming our chatbot via the "Webchat"-integration.

      But to be honest i don't understand what i need to change else.

      Thanks for your help!

       

       

       

      Author's profile photo Gregory Arouche
      Gregory Arouche

      Hello,

       

      We are also using the Webchat integration, we'd like to know what we should do, is the project ready for those changes ?

       

      Thanks