Principal propagation in a multi-cloud solution between Microsoft Azure and SAP Business Technology Platform (BTP), Part IV: SSO with a Power Virtual Agents Chatbot and On-Premises Data Gateway
Note: This blog post is the fourth part of a tutorial series. If you arrived here without reading the first, second and third part, please do so before you continue, and then come back here again. Part I describes principal propagation between Microsoft Azure, calling a simple Web Service deployed on SAP Business Technology Platform (BTP, which now integrates SAP Cloud Platform, SCP). Part II extends the scenario by propagating the Azure-authenticated user via BTP and SAP Cloud Connector to an SAP Gateway system for displaying the user’s data. Part III adds a business application to the scenario connecting common platform services in Microsoft Azure and SAP BTP for principal propagation in the context of a chat bot in Microsoft Teams.
A live demo of the chat bot scenario in part III is also available on Episode #31 of the SAP on Azure Video podcast series (starting at min 23:30) from Holger Bruchelt, Goran Condric, and Robert Boban.
Implementing the Teams chatbot with Power Virtual Agents and Power Automate
Part III introduced a real-world business application to the scenario by adding a Microsoft Teams-based chat bot which allows the user to order new IT equipment from a product catalogue managed by the ABAP backend. The bot is implemented in C# using the Bot Framework Software Development Kit (SDK) along with the Azure Bot Service, which enables the classical or “pro-code” developer to create a compelling chat bot experiences. This includes single sign-on (SSO) from Teams and end-to-end principal propagation with the Azure AD-authenticated user when accessing the product data in the backend system. You can find the complete source code of the bot in GitHub. The dialog between the user and the bot is implemented as a Waterfall dialog from the SDK by defining the series of steps to collect information from the user and to guide her through a series of tasks.
Part IV of the blog series (this post) builds the same chatbot user experience with Microsoft’s low-code interface Power Virtual Agents (PVA). PVA provides a code-free graphical interface to define the conversational flow with the user. A PVA-based bot can be installed as an app in Teams and provide SSO for the Azure AD-authenticated user – similar to the implementation in part III.
The following diagramm shows the dialog flow of the product search bot from the graphical toolset in PVA:
The conversation is triggered by phrases, keywords, or questions that a user is likely to type when looking for a new product in the catalogue. The conversation with the bot starts with an authentication node. Upon successful login, a set of variables are available to the following nodes, such as the access token issued to the bot (
bot.AuthToken) containing the logged-in users information. Next, the use has to type in the search term to look for in the SAP system’s product catalogue, which adds another variable (
productID) to the dialog.
To automate activities and call the backend system, the PVA-based bot uses Flows in Microsoft Power Automate (PA). Similar to PVA, PA provides a workflow engine with a point-and-click flow designer to build the business automation logic. In this scenario, the product search bot uses two Flows in PA:
- The Exchange Token Flow is called by the bot to obtain an SAP-issued OAuth access token for the Azure AD-authenticated user. It essentially covers the token exchange logic for principal propagation that is implemented by the SCPClient class in the Bot Framework-based version of part III. The step Exchange AAD JWT to AAD SAML Assertion uses the on-behalf-of flow to exchange the bot access token (obtained via the
bot.AuthTokenvariable and passed as the input parameter
AADJWTto the flow) into a SAML assertion for the user. Next, the Get SAP Bearer Token with SAML Assertion step in the flow uses a secure connection to the SAP backend system to request an access token for the product search OData service according to RFC 7522 . This requires a valid OAuth client configured in the SAP backend system to authorize the token request, and a user in the backend system who matches the common identity attribute (such as the email address) of the user in Azure AD. The flow returns the access token found in the SAP backend system’s token response message to the PVA bot as a new variable (
- The Call SAP OData Service Flow gets the SAP-issued OAuth access token as an input parameter and passes it in the Authorization Header (according to RFC 6750) to the SAP backend system call of the Product Search OData service, along with the product id entered by the user in the chat bot.
Accessing the CDS OData service via On-Premises Data Gateway
Power Automate Flows make use of Connectors to integrate with other services and systems. The HTTP with Azure AD connector can fetch resources via HTTP(S) from various Web services, or from an on-premise service. For the latter use case, the connector can be configured to use a gateway component from Microsoft which provides a secure connection between the corporate network and the Cloud. The On-Premises Data Gateway (OPDG) provides a similar functionality as the SAP Cloud Connector (SCC) introduced in part II of the blog series by establishing an outbound connection from the corporate network to the Cloud. Thus, it is not required to open any inbound ports in your corporate firewall.
You could configure the HTTP with Azure AD connector in the Power Automate Flows to request the OAuth access token from the XSUAA token endpoint and fetch the product catalogue data via the iFlow-exposed URL from SAP Cloud Platform Integration (CPI) as implemented in the SDK-based bot in part III. However, this part of the blog series proposes an alternative solution using the OPDG. Unlike SCC, OPDG has no built-in support for principal propagation to generate short-lived certificates based on an incoming OAuth access token from the Cloud, but it securely forwards HTTP(S) requests from the Cloud to the SAP backend. Therefore we will now get the SAP-issued OAuth access token directly from the backend (and no longer from XSUAA), and call the Product Search OData service directly from the PA Flow (and not via CPI).
Compared to the solution in part III, the OPDG-based approach slightly reduces the total number of steps to call the product search service with the Azure AD-authenticated user from the bot. The complete end-to-end flow is illustrated in the following diagram:
- Similar to part III, the bot is started by the already logged-on user in Microsoft Teams. The PVA-based Product Search bot sends back a message to tell Teams to obtain an authentication token for it.
- By configuring single sign-on for the PVA bot and adding the corresponding authentication node to the conversation flow, the bot requests an access token from Azure AD using the user’s session. This requires the registration of an application representing the PVA bot in Azure AD. Since the user is already logged-on in Teams, this step does not ask the user to re-enter her credentials.
- Azure AD returns the access token to the bot which contains the required identity information such as the user’s email address. The token is now accessible via the
AuthTokenvariable to any following steps in the conversation. After successful (single) sign-on, the bot asks the user to enter the id of a product to search for in the catalogue managed in the SAP backend.
- Next, the bot starts the token exchange process as described above with the Exchange Token flow in PA. The assertion is configured by the SAML settings of an Enterprise application registration in Azure AD for the SAP backend system.
- The Exchange Token flow uses the HTTP with Azure AD connector and an on-premise connection via the OPDG to send the SAML assertion with an access token request to the SAP backend system’s OAuth Authorization Server. Compared to the XSUAA-issued access token in part III, the token from the SAP backend system is not a JSON Web Token, but a bearer token. Bearer token do not self-contain the digitally signed identity information of the user and authorized scope(s), but are essentially a “pointer” to this data in the system that issued the token.
- Finally, the bot invokes the CDS-based OData Product Search service on-behalf-of the Azure AD-authenticated user by passing the bearer token to it. Again, the HTTP with Azure AD connector is used and configured via an OPDG connection to request the data for the user-provided product ID securely via the encrypted tunnel.
With the above changes to the solution architecture, the following additional configuration settings must be applied in the SAP backend system:
- A trust relationship between Azure AD and the OAuth Authorization Server in the SAP backend, which is required for the Exchange Token PA flow to successfully request the access token using the SAML Bearer Assertion Grant. Otherwise, the SAML assertion signed by Azure AD will be rejected by the SAP backend’s OAuth server.
- Setup of an OAuth client for the Exchange Token PA flow to request the access token from the backend’s OAuth Authorization Server.
- Enhancing the existing PRODUCT_SEARCH role created in part III in the SAP backend with the S_SCOPE authorization object to match the backend user’s permissions with the requested scope of the OAuth client.
- Configuration of the SSL server to provide a secure connection between the OPDG and the SAP backend system. This requires a TLS certificate with a common name (CN) of the SAP backend’s full qualified domain name (FQDN). The certificate’s issuer (certificate authority, CA) must also be trusted by the OPDG. You will re-use the OpenSSL-based corporate CA configured in part II of the blog series.
Before you get started with the items above, make sure to meet the following prerequisites:
- Ensure that SAML is enabled in your SAP backend system. If it is not enabled yet, use transaction SAML2 to configure your SAP system as a Service Provider as described here.
- Ensure that the required ICF nodes under /sap/bc/sec/oauth2 are activated. You can check with transaction SICF their current status:
- To build the PVA bot, you can use your Microsoft 365 E5 developer subscription to sign-up for a free Power Virtual Agents trial license with your developer subscription’s admin account. You should also install the Users sample data pack in your developer subscription which will create a set of test users in your subscription’s Azure AD tenant.
- Download and install the OPDG by following these instructions. The hosts running OPDG and your SAP system must have network connectivity. Make sure that you choose the region matching your PVA environment’s region. You should see a status page in your OPDG instance like this:
- Checkout the branch
part4of the blog series GitHub repository with a Git client of you choice:
git clone https://github.com/raepple/azure-scp-principal-propagation.git cd azure-scp-principal-propagation git checkout part4
Setup TLS in the SAP system
Login with SAP GUI and start transaction STRUST. Switch to the change mode (Ctrl+F1) and double-click on the SSL server Standard node.
Right-click and select Replacement Wizard from the context menu.
Enter the distinguished name (DN) of the new SSL certificate with the full-qualified domain name (FQDN) of your SAP system as the Subject Alternative Name (SAN) with the “DNS=” attribute following this pattern:
DNS=<FQDN>, OU=<Org Unit>, O=<Organization>, C=US, CN=<FQDN>
In a scenario setup using the ABAP developer trial system, you could choose a FQDN like “vhcalnplci.bestrun.corp“, which results in the following DN as shown in the screenshot:
DNS=vhcalnplci.bestrun.corp, OU=SAP Team, O=BestRun, C=US, CN=vhcalnplci.bestrun.corp
Click Choose Distinguished Name.
|3||Keep the proposed algorithm and key length and click on Select Algorithm.|
|4||Click Create Key Pair.|
Click Save as local file and save the new Certificate Signing Request (CSR) as a new file, e.g. vhcalnplci.csr, to your OpenSSL (see part II) installation’s subdirectory trustedca/csr.
Open a command line and change to the subdirectory trustedca of the OpenSSL installation. Run the command
to sign the CSR.
Go back to the replacement wizard.
Click Load local file and select the signed certificate response file
Open your OpenSSL Trusted CA’s signing certificate (trustedca/trustedca.crt) in a text editor.
Copy the content into the clipboard and paste it at the end of imported certificate response file content (after the
Click Import Certificate Response.
|9||Click Activate New Key Pair and Certificate.|
|10||Click Back (F3).|
You should now make sure that the host running your OPDG can reach the SAP system under the specified FQDN (e.g. vhcalnplci.bestrun.corp).
For testing purposes you can resolve the chosen FQDN on the OPDG host to the SAP system’s IP address by adding a new entry to the OPDG’s hosts file (C:\Windows\System32\drivers\etc\hosts), e.g.
The OPDG host must also trust the issuer of the SAP system’s new TLS certificate to successfully establish a secure connection. Therefore, open the Certificate Management console on the OPDG host and import the TrustedCA’s signing certificate.
Run certlm.msc on the OPDG host. Select Trusted Root Certification Authorities from the list.
Right-click and select All tasks -> Import from the context menu.
Select the TrustedCA’s signing certificate (
|14||Click Next and Finish to complete the import wizard.|
You have now successfully setup secure connectivity between your OPDG instance and the SAP backend.
Setup trust and federation between Azure AD and the SAP OAuth server
|15||Start transaction SAML2 in SAP GUI, and click on Metadata.|
|16||Select Service Provider and click on Download Metadata.||
Login to Azure Portal with your Microsoft 365 E5 developer subscription’s admin account and select Azure Active Directory from the portal menu.
Select Enterprise Applications from the left-side menu.
|18||Click New application.|
Enter “SAP NetWeaver” in the search box of the Azure AD Gallery.
Click on the SAP NetWeaver tile from the search result.
|21||Click the tile Set up single sign on.|
Click on Upload metadata file and choose the file your downloaded in step 2.
Store the Identifier (Entity ID) in a temporary file. You will need the value later when configuring the bot.
Change the Reply URL from the metadata file import according to the following pattern:
https://<SAP FQDN>:<SSL port>/sap/bc/sec/oauth2/token
Replace <SAP FQDN> with the full-qualified domain name you configured during SSL setup in step 2, e.g.
For the required Sign On URL, enter any valid URL, e.g. https://vhcalnplci.bestrun.corp:44300/nwbc. This value is not relevant for the scenario.
|25||Close the Basic SAML Configuration settings and click on the Edit button for the User Attributes & Claims setting.|
|26||Click on the Unique User Identifier (Name ID) claim.|
|27||Choose user.mail from the Source attribute drop down list and click Save.|
Close the User Attributes & Claim settings.
Click on the Download link of the Certificate (Raw) for the app’s SAML Signing Certificate.
|29||Repeat the previous step with the Federation Metadata (XML) Download link.|
Go back to transaction SAML2 and switch to the tab Trusted Providers.
Select OAuth 2.0 Identity Providers from the drop-down list.
|31||Click Add and select Upload Metadata File|
|32||Select the metadata file from Azure AD you downloaded in step 29 and click Next.|
|33||Select the SAML signing certificate from Azure AD you downloaded in step 28 and click Next.|
|36||For the new trusted identity provider, click Edit to configure the federation settings.|
|38||Select E-Mail to match the Name ID claim setup configured for Azure AD in step 27 and click OK.|
|40||Click Enable and confirm with OK.|
You have now setup trust between your Azure AD tenant and the SAP backend OAuth server. Identities are federated based on the e-mail address. To authorize the PVA bot to request an access token from SAP, an OAuth client is needed and will be configured in the next step.
Configure the SAP OAuth Client
The new OAuth client requires an existing system user associated with it. Therefore, begin with transaction SU01 and enter CHATBOT for the new user’s name.
|42||Enter a Last name (e.g. “Chatbot client”) and switch to the Logon Data tab.|
Select System from the User Type drop-down list, and enter a New password. This will be the OAuth client secret used by the PVA bot when requesting the access token.
|44||Start transaction SOAUTH2.|
For the OAuth 2.0 Client ID, open the value help and select the previously created CHATBOT user.
Provide a description of the new client (e.g. “Client for PVA Chatbot”).
|47||Deselect the checkbox for SSL Client Certificate and click Next.|
Open the value help for Trusted OAuth 2.0 IdP and select the previously created identity provider for your Azure AD tenant from the list.
Select the first row in the Scope Assignment table and open the value help for the OAuth 2.0 Scope ID.
Select ZPRODUCTSVIEW_CDS_0001 from the search results.
Note: If this scope does not appear in the list, go back to part III of the tutorial series and ensure that you enabled OAuth for the CDS view according to steps 18-21.
Next you need to align the permissions for the end user to match the OAuth scope assigned to the new OAuth client. The bot cannot request an access token from SAP on behalf of the user if the user’s assinged role does not contain the permission for the requested scope(s). Therefore you will update the existing PRODUCT_SEARCH role in the next step.
Update the backend authorizations
Start transaction PFCG and enter PRODUCT_SEARCH in the Role entry field.
|52||Switch to the Authorizations tab and click on Change Authorization Data.|
Enter S_SCOPE in the first row of the table.
Open the tree view for the fields of the S_SCOPE authorization object.
Change the value of the field OA2_CLIENT to limit access to only a selected OAuth client.
Click the pencil symbol for the field.
In the first row of the table, click on the value help of the From column.
Select the user CHATBOT from the list and click Copy.
Change the value of the field OA2_SCOPE to limit access to only a selected OAuth scope.
Click the pencil symbol for the field.
|59||In the first row of the table, click on the value help of the From column.Select the scope ZPRODUCTSVIEW_CDS_0001 from the list and click Copy.|
|61||Click Save, then Generate|
With this step all required changes in the SAP backend are completed. Let’s continue with the implementation of the bot and flows, which are available as a solution ready to import into your power platform environment. You will use environment variables to configure the solution according to your scenario setup.
Import and configure the solution
Register a new application in Azure AD for the PVA bot.
Select Azure Active Directory from the Azure Portal menu and click App registrations on the left-side navigation.
|63||Click + New registration|
Enter a name for the new app (e.g. “Product Search Bot PVA”).
Select the option “Accounts in this organizational directory only (<tenant name> only – Single tenant)” for Supported Account Types.
For the Redirect URI, keep “Web” and enter “https://token.botframework.com/.auth/web/redirect” to support Teams-based SSO.
Select Overview from the left-side navigation. Click Copy to clipboard next to the Application Client ID and store it in a temporary file. Also Copy to clipboard and store the Directory (tenant) ID.
You will need these values later for the configuration of the PVA solution.
|66||Select Certificates & secrets from the left-side navigation and click + Client secret|
|67||Enter a name (e.g. “PVA”) and click OK.|
|68||Click on Copy to clipboard and store the secret in a temporary file. You will need it later for the configuration of the PVA solution.|
Select API permissions from the left-side navigation and click on Grant admin consent for <tenant name> to suppress consent confirmation from users when using the bot.
Confirm with OK.
To suppress consent confirmation when requesting the SAML assertion for the user, the SAP NetWeaver app must authorize the bot app.
Click on your Azure AD directory name in the breadcrumb navigation.
|71||Switch to the All applications tab and select the SAP NetWeaver (enterprise) app from the list.|
|72||Select Expose an API from the left-hand navigation menu and click on Add a client application.|
Enter the Client ID from step 65, activate the checkbox for the user_impersonation scope.
Click Add application.
|74||Next, sign in to Power Apps. Select Solutions from the menu to import the solution.|
Select the file
Wait for the notification Solution “Product Search Bot” imported successfully.
Then select the solution Product Search Bot from the list.
|79||Click on the BotAppClientID environment variable in the list.|
Enter the Application Client ID from step 65 in the field Current Value.
|81||Repeat the previous two steps for the following environment variables and values:
Select the Call SAP OData Service flow from the solution’s component list.
Power Automate opens in a new browser tab.
|84||Select the second step in the flow and click on the button + New connection reference to fix the current issue with the missing connection.|
|85||Enter the following connection settings:
Note: If you don’t see your OPDG instance listed in the Gateway drop-down box, check under Data -> Gateways the list of connected data gateways. You may have chosen a wrong region when installing the gateway if it is not listed. If your Power Platform environment’s region is Europe, choose West Europe as the region for your OPDG. Also make sure that your OPDG instance is online and connected.
As you can see from the configuration of the step, the request is sent with an Authorization header containing the SAP access token passed as an input value to the flow. It also uses the product id passed as the second input value in the query string. Finally, the environment variable SAPODataServicePath is used to set the path for the request to the OData service.
|87||Click on the Back button.|
|88||Click Turn on to activate the flow.|
|89||Go back to the previous browser tab of the Power Apps portal and click on Done.|
Select the Exchange Token flow from the solution’s component list.
Power Automate opens in a new browser tab.
|92||Select the 4th step in the flow and click the link invalid connection.|
|93||Enter the following connection settings:
|96||Click Turn on.|
Go back to the previous browser tab of the Power Apps portal and click on Done.
Select the Product Search Bot from the solution’s component list.
A new browser tab opens the bot in Power Virtual Agents.
Select Manage -> Channels from the left-hand navigation.
Click on the tile for Microsoft Teams.
|99||To enable the Teams channel for the PVA bot, click on Turn on Teams.|
|100||Click on Submit for admin approval.|
|101||Scroll down and click on Copy to copy the App ID for the PVA bot used by Teams for SSO.|
Go back to the Azure Portal and select Expose an API from the menu.
Click on Set to define the Application ID URI.
Set the Application ID URI according to this pattern:
Replace app-id with the value in the clipboard from step 101.
|104||Click + Add a scope.|
Choose a name of the new scope (e.g. “Product.Read”), select Admin and users for consent, and enter the required display name and consent description.
Click Add scope.
|106||Click + Add a client application|
Add the client id
to the list. This is the id of the Teams mobile/desktop application. By adding it here you will avoid that users in Teams are asked to give their consent when using the PVA Product Search Bot.
Click Add application.
Repeat this step and add the client id
for the Teams web application.
Go back to the Power Virtual Agents browser tab and click Close.
Select Manage -> Security from the menu.
Click on the Authentication tile.
|109||Enter the following authentication settings for the bot:
|110||Confirm with Save.|
Wait for the notification that the authentication settings are saved.
Click on the link Go to publishing.
|113||Confirm with Publish.|
You’ve now successfully deployed and configured the solution containing the PVA chatbot and PA flows. Let’s test it in Microsoft Teams.
Test the PVA chatbot in Microsoft Teams
|114||Go to Manage -> Channels.Click on the tile for Microsoft Teams.|
|115||Click Open bot|
You are asked to sign-in to Teams.
Note: Login with a user from your Azure AD tenant who has an email address matching a user in your SAP system with the same email address.
|118||Enter a trigger phrase from your bot’s topic, e.g. “Purchase a new notebook”|
You get single signed-on to the bot, and your bot’s OAuth access token is displayed.
Enter a product id search term, e.g. “HT”.
The bot will search for products in the backend according to the currently logged-on user’s authorizations for product categories, e.g. Notebooks.
In the search results, only Notebooks matching the entered product id are displayed.
Note: You can copy the Base64-encoded token and decode its content with https://aka.ms/jwt.
You can change the user’s authorizations in the backend by changing the corresponding authorization object.
Go to transaction PFCG in SAP GUI and change the authorization field PDCATEGORY from Notebooks to Headsets.
Save the changes and re-generate the profile (see step 61)
|121||Start a new search in the bot. Again, enter the search term “HT” when asked by the bot for the product id.|
|122||This time, the search results only inlcude headsets with the matching product name.|
Again, I hope you enjoyed extending the integration scenario for principal propagation with Microsoft Power Platform and the on-premises data gateway.