[SAP & MS Teams] 3 – Requirements and application architecture
Welcome back to the blog post series about how to create your own Microsoft Teams extension using SAP BTP and Microsoft Azure. In today’s third blog post, I will provide you with all relevant details of the architecture and important security principles that your Microsoft Teams extension is based on.
As explained in the first blog post (click here), this sample Microsoft Teams extension for SAP SuccessFactors will allow you to create leave requests right from within Microsoft Teams. It also provides features for managers to approve or reject leave requests. As explained in the preface, this blog post series has a special focus on those customers interested in or already using the SAP Business Technology Platform and corresponding integration services.
The series will be published in multiple editions which are structured the following.
- Preface and scenario introduction (click here)
- Target application features (click here)
- Requirements and application architecture (this blog post)
- Check the availability of this scenario’s system requirements
- SAP SuccessFactors instance
- SAP Business Technology Platform services
- Microsoft Azure and Teams subscription
- Understand the detailed architectures
- Communication from Microsoft Teams to SAP SuccessFactors
- Communication from SAP SuccessFactors to Microsoft Teams
- Security aspects of the architecture design
- Check the availability of this scenario’s system requirements
- SAP BTP subaccount configuration and test users (click here)
- SAP SuccessFactors instance setup (click here)
- Set up your SAP Cloud Integration instance (click here)
- Get your Microsoft Azure settings ready (click here)
- Deploy your Microsoft Teams extension (click here)
- Improvement ideas and further topics (click here)
A quick reminder for your convenience – Feel free to check out the GitHub repository provided in the SAP-samples organization. Please be aware that the repository is still being updated, so make sure you’re pulling on a regular basis.
So, let’s get started with today’s edition and check out the system requirements to accomplish the development of this extension application. Fasten your seat belts, as this will be the longest and probably most complicated part of this blog post series – but also the most interesting one!
Important – Please don’t worry if you don’t understand the whole architectural concepts at first glance. In particular topics like SAML and the On-Behalf-Of flow can be outlined in a much greater detail. But as this is not the major purpose of this blog post series, try to get the gist and the purpose of what these ideas serve – and if you’re really interested, there’s tons of information available on the world wide web. Take this chapter as a reference for the upcoming technical implementation. Things will become clearer once you’re setting up the application yourself!
The system requirements for your Microsoft Teams extension application can be split up based on the different landscapes that you will use in this scenario. Let’s start with the most obvious component required for the leave request scenario – SAP SuccessFactors.
This sample application has been implemented using an SAP SuccessFactors Salesdemo instance. As you will be using your own landscape and probably also a different release version, you might encounter new interfaces or issues which we cannot foresee as of today. Please be aware of this when comparing screenshots to your own landscape. Make sure your SAP SuccessFactors instance and privileges fulfill the following requirements.
- Access to Intelligent Service Center must be given
- Employee Central must be in use for API access
- Time Off (incl. workflows) needs to be configured
- Administrative system access is required to
- Define required OAuth2 clients
- Create a technical API user and assign permissions
For the scenario, besides API access via Principal Propagation, also technical user access is required. Therefore, please make sure you are in possession of a technical user with permissions to read basic information of all users (e.g., email addresses) and read access for all leave requests.
In our sample, we made use of a super admin for this purpose (e.g., sfadmin). Whereas this might be a viable option for a demo landscape, it is not advisable for a productive system. Please make sure to use a dedicated API user in this case, with the least possible privileges. To find out about the API endpoints used, check the integration flows provided at a later point in time and assign permissions to your technical user accordingly.
If required, check out the following SAP Note to find out how to create a super admin user for your SAP SuccessFactors instance (click here).
I don’t have an SAP SuccessFactors instance – Where can I get one?
Please get in contact with your SAP representative to find out whether you are eligible for an SAP SuccessFactors demo system. If you want to use your existing SAP SuccessFactors instance, we highly recommend using a suitable sandbox system only!
SAP Business Technology Platform
The SAP Business Technology Platform will be the heart of your extension application. On the one hand, it will host the runtime instance of your extension application which for example provides the bot handler implementation and a React component.
On the other hand, it provides integration capabilities using the SAP Cloud Integration component of your SAP Integration Suite. This is where the data wrangling and the Principal Propagation to SAP SuccessFactors takes place. Within your SAP BTP environment, please make sure you meet the following prerequisites.
- Administrative subaccount access required
- Cloud Foundry space developer authorizations
- SAP Integration Suite instance available
- Memory/Runtime quota assigned (~256MB)
- Process Integration Runtime quota assigned
Info: A trial or free tier subscription should be sufficient to develop this extension application. Nevertheless, in this case, the usage of SAP Integration Suite is possible for 90 days only. After 90 days your tenant is decommissioned, and you need to repeat some of the steps described in the upcoming blog posts. For the usage of SAP Task Center, you will need a paid SAP BTP subscription, as well as a custom IAS/IPS instance. As the SAP Task Center integration was already part of the Advanced Scope scenario, it will not be described in further detail within this blog post series.
SAP BTP subaccount
Cloud Foundry space
Microsoft Azure & Microsoft Teams
As you might have expected, you will also make use of different Microsoft Azure components and of course – Microsoft Teams. Within your Microsoft Azure environment, you will maintain app users, define application registrations (including required scopes and permissions), and configure the trust between Microsoft Azure and SAP BTP. Furthermore, you will make use of relevant service offerings to run your bot in the Azure environment. Let’s see which Azure components are used by your extension application to give the user a harmonized and integrated experience.
- An Azure Active Directory instance with administrative access is mandatory
- A valid Azure subscription (paid or trial) for paid services
- An Azure Bot service instance to connect your bot with Microsoft Teams
- The bot requires an Azure Storage account to persist some information
- And a Microsoft Teams subscription to test your extension application
Info: An Azure trial subscription should be sufficient to cover these requirements. If you want to use the extension beyond the trial period, you will need to switch to a paid subscription. Concerning a valid Microsoft Teams license, please check if you’re eligible for a free Microsoft Teams Exploratory license. This replaces the need for a Microsoft Office 356 (Developer) subscription. You will learn in one of the upcoming blog posts how to activate the Exploratory license (if eligible!).
Azure Resource Group
Teams Exploratory license
This scenario only works in environments in which your Active Directory users have the same email address as the corresponding SAP SuccessFactors users. If this requirement cannot be fulfilled, the Principal Propagation will not work. There might be further options like username mapping, which have not been evaluated yet. If you’re planning to follow this sample scenario, make sure you create at least two test users in Azure Active Directory and SAP SuccessFactors with matching email addresses. A sample mapping can be seen in the following screenshot.
Well, that’s it for the system requirements section. Except for the SAP SuccessFactors instance, you should be able to build the whole Microsoft Teams extension application using trial or free tier subscriptions of SAP Business Technology Platform and Microsoft Azure. Let’s check out the architecture details next.
The architecture of your extension application can be split into two parts. The integration between Microsoft Teams and SAP SuccessFactors and vice versa. Today’s blog post puts a focus on the most important communication aspects between the different landscape components and gives you a high-level understanding of the Principal Propagation flow. As always feel free to check out the GitHub repository to dig deeper (click here).
Please keep in mind that this sample application is supposed to prove the technical feasibility of integrations between SAP solutions like SuccessFactors and Microsoft services. It provides a baseline architectural guidance, which can be further enhanced by advanced components and other use cases in the future.
For example, by evolving features of the SAP Identity and Authentication service, the usage of XSUAA could be replaced in the near future. The usage of SAP Event Mesh could help you to improve the handling of notifications and allow you to store them in a message queue instead of directly sending them to Microsoft Teams. This would make notifications also consumable for other channels.
These are just two examples for a future evolution of this Microsoft Teams extension application. Take the current sample as inspiration to get started with and feel free to adapt it to your personal needs, including further service offerings on the SAP and Microsoft side. So, let’s get started with the architecture and see how Microsoft Teams talks to SAP SuccessFactors.
Microsoft Teams to SAP SuccessFactors
The communication from Microsoft Teams to SAP SuccessFactors is primarily based on the Principal Propagation approach. The idea of Principal Propagation consists in forwarding or “propagating” an authenticated user (principal) between different systems. This allows you to use the extension application without additional logins on the SAP BTP or SAP SuccessFactors side. All involved architecture components make use of your authenticated Microsoft Teams session.
With the extension application and its different entry points (chat bot, messaging extension, tab), the actual user authentication to Microsoft Teams varies slightly. As the blog post is focusing on the Principal Propagation between Microsoft Azure and SAP SuccessFactors (and not the Microsoft Teams authentication itself) the actual entry point is of little importance for you. Once the user has opened the app’s door (meaning an authenticated session/token is available), the Principal Propagation flow is almost similar for all entry points. In the following we will use the sample scenario of a chat bot conversation.
Okay, enough introductory words! Let’s find out what’s happening from the moment you open your Microsoft Teams client until your leave request is created in SAP SuccessFactors using the chat bot feature.
Hint: Please be aware, this architecture is simplified, as the interaction between Microsoft Teams and the extension application makes use of the Azure Bot Service. A direct 1:1 communication as visualized does not happen. It has been depicted here for an easier understanding.
1 – Let’s assume that a user is already signed into Microsoft Teams and starts the bot. The bot handler (part of the extension application running on SAP BTP) is called and asks the Microsoft Teams client to obtain an authentication token for the current user, by sending a so-called OAuthCard to the client.
2 – The Microsoft Teams client fulfills this request and obtains a bot application token from Azure Active Directory using the session of the current Microsoft Teams user. This process might require an initial login on first usage of the extension application, including a potential consent for scopes or a Multi-Factor authentication (MFA).
3 – If the current session can be used to obtain a valid token from Azure Active Directory, this bot application token is sent to the Microsoft Teams client, which sends it back to the bot handler of your extension application. Depending on the data required, this token can now be exchanged for an application access token including scopes for Microsoft Graph or a custom scope allowing you to obtain a SAML Assertion for SAP BTP access (more details will be provided later!).
4 – In case of SAP BTP access, the extension application/bot handler exchanges the application access token for a SAML Assertion containing the user’s attributes and unique identifier. For this step, the so called On-Behalf-Of (OBO) flow (click here) is used. Obtaining a valid SAML Assertion is based on a trust configuration between SAP BTP and your Azure Active Directory.
5 – The SAML Assertion is sent to the SAP BTP authorization server (XSUAA) to receive an access token for the SAP BTP environment. This token request needs to contain a valid Client Id and Secret, which is taken from a service key of the Process Integration Runtime. This process of exchanging a SAML Assertion provided by one platform for a valid token of another platform follows the RFC 7522 standard (click here).
6 – Using the access token received by XSUAA in exchange for the SAML Assertion, the extension application/bot handler can now call the integration flows of your SAP Cloud Integration instance with the propagated user identity.
7 – The integration flows now make use OData services exposed by SAP SuccessFactors and return the result to the extension application. The OData requests from SAP Cloud Integration to SuccessFactors are secured by a standardized OAuth2 SAML Bearer Assertion, allowing the required Principal Propagation on the last mile.
That’s it – not so complicated at all, is it? Let’s sum it up briefly once again:
- Take the Microsoft Teams session as initial authenticated user context
- Use it to retrieve an initial authentication token from Azure Active Directory
- Take that token to obtain an application access token based on your application registration
- Use the On-Behalf-Of flow to get a valid SAML assertion for SAP BTP environment access
- Exchange the SAML assertion to an XSUAA token valid for SAP Cloud Integration access
- Use Principal Propagation features of SAP Cloud Integration to call SAP SuccessFactors
If you want to get a better understanding of the Principal Propagation approach used, I once again highly recommend reading the blog post series by Martin Räpple (click here). He describes the approach in great detail, while building a Microsoft Azure based chat bot for SAP S/4HANA. Another recommended resource is the following Microsoft documentation (click here), covering Single-Sign-On for bots.
I hope you got a first understanding of how Principal Propagation is being used in this scenario. Feel free to check out the GitHub (click here) to get an even better understanding of what’s happening behind the scenes. Okay, let’s tackle it the other way round now! How does SAP SuccessFactors talk to Microsoft Teams.
SAP SuccessFactors to Microsoft Teams
This communication direction is required for sending notifications to Microsoft Teams, once a leave request in SAP SuccessFactors is created or updated and your extension application users need to be notified.
As SAP SuccessFactors notifications do not contain any kind of user context, the concept of Principal Propagation cannot be applied here. Principal Propagation usually starts with an authenticated user session/token, which can be used for the further process. In our case, this prerequisite is not given so a communication based on technical users has to be used.
The following part of the blog post will guide you through the different steps of this communication and give you a high-level understanding before you can dive into some specific details of the architecture.
Hint: As already explained for the first architecture diagram, there will never be a direct communication between the Microsoft Teams client and the bot handler of the extension application. This interaction always uses the Azure Bot Service. Furthermore, in this architecture the XSUAA instance, used to authenticate calls from SAP Cloud Integration to your extension application, is not depicted. You can find further details on this XSUAA instance in the next chapter.
1 – Imagine, a leave request is created or changed. This triggers an event in the so-called Intelligent Services Center of SAP SuccessFactors. No matter if the leave request was created from Microsoft Teams or using SAP SuccessFactors.
2 – This event is forwarded to SAP Cloud Integration via a secured SOAP endpoint. The required Client Id and Secret are maintained on SAP SuccessFactors side, to allow secure communication of events between the two applications.
3 – SAP Cloud Integration receives the event and requests additional information from SAP SuccessFactors using a technical user. This allows you to enrich data like email addresses of the event recipient and sender and further content not included in the original event.
4 – SAP Cloud Integration can also request additional information from Microsoft Graph (if required). This has been successfully tested but is currently not being used.
5 – From SAP Cloud Integration, the event (enriched with additional data), is forwarded to the notification endpoint of your extension application. This endpoint is secured by XSUAA, and the required credentials are stored in SAP Cloud Integration.
6 – Once the notification arrives, the extension application extracts the receiver from the event data and his or her corresponding conversation reference is read from the Azure Blog Storage. This reference (uniquely identifying a communication between a bot and a user) allows Microsoft Teams to send the notification to the correct recipient.
7 – Once the reference is available, the notification can be delivered to the recipient user in Microsoft Teams. The notification contains all essential information, like the sender, the recipient and the leave request details – all nicely presented in an adaptive card.
8 – In case of new leave request, a recipient can now make use of available actions buttons (Approve/Reject). This will load a so-called Microsoft Teams task module (popup), which is rendering a tiny React component (check out the client folder in the GitHub repository).
9 – Using the authenticated session context available in the React component, a similar token exchange process can be started, as already described in the first architecture. This way the leave request workflow can now be securely updated using the familiar Principal Propagation approach between Microsoft Teams and SAP SuccessFactors. Therefore, a dedicated API endpoint of your extension application is used by the React component, which in turn triggers the respective logic in your coding to update the workflow status in SAP SuccessFactors using Principal Propagation.
Usage of a task module
The feature to approve or reject leave requests (by clicking on action buttons within the notification) has been implemented in so-called task module. The task module popup loads a tiny React component which is rendered in the user’s Microsoft Teams client. See the following sample, which was also part of the second blog post (click here). From minute 1:08 onward, you will see the task module popup when a user approves or rejects a leave request.
So, what’s happening here? Once the user clicks on the available action buttons, the Microsoft Teams client receives the URL of the React component and renders it in a popup. The user’s session context (available within the runtime of this React component) allows you to make use of Principal Propagation again. This is essential to approve or reject the leave request workflow with the identity of the current user. Using a dedicated API endpoint of your extension application, the required logic can be called from your React component, passing in the token/identity of your authenticated user. The same concept can also be used for scenarios in which you want to develop a custom tab extension as the required session context for Principal Propagation is also available in this case.
Hint: The tab component of our sample extension application is making use of adaptive cards sent from the bot handler, which is a much more convenient and simple option in case you don’t want to create your own React component. Nevertheless, the coding used for the task module should give you a good idea how to create your own custom tab extension including Principal Propagation.
Why do we need a custom React component in the task module?
Well yes, the task module including a custom React component for approving or rejecting leave requests doesn’t make the architecture easier. It’s an additional complexity just used for triggering an authenticated API call to the extension application (allowing Principal Propagation) and for showing a confirmation message.
Task Module loading
The main idea of the task module popup is, not to interrupt a potential user-bot conversation by triggering a new message once a user clicks on Approve or Reject. The initial approach was to build a task module entirely based on adaptive cards instead of a custom React component. However, as the first step of rendering an authentication card in the task module failed, this approach had to be discarded.
Therefore, the current implementation makes use of a custom React component. This flexible approach allows you to access a user’s session context during runtime, which contains a valid token for further authentication flows, including Principal Propagation.
Sounds like some extra effort, but keep in mind that the usage of custom tabs usually requires you to build a custom React component anyhow. In case you want to have your own tab extension one day, you can just simply follow the same approach for Principal Propagation, which has been used in this task module implementation. Just with the difference of rendering your React component in a tab instead of a task module.
Hint: Please be aware that in case of a custom React component, the exchange of the initial token (obtained from the session context) for a valid application access token (e.g. for Microsoft Graph access), needs to be done manually via a dedicated call to the Azure Active Directory token endpoint. In scenarios including the bot handler, there’s a simplified option to do so.
Details on security aspects
As security is one of the central aspects of your extension, here are a few more details which will make the whole architecture hopefully less confusing.
Your Microsoft Teams extension is protected by multiple security aspects. This includes for example the use of delegate permissions for Microsoft Graph access and a Principal Propagation approach for the communication between Microsoft Teams and SAP SuccessFactors.
Secondly, a XSUAA instance protects the custom API endpoints used by the React component of your task module and by SAP Cloud Integration for sending notifications. Finally, secure communication between SAP SuccessFactors and Cloud Integration is ensured by using client credentials of the Process Integration Runtime.
That’s a short summary for those of you in a hurry and those who don’t care too much about security details. All other interested readers will find further details below.
a1 – Microsoft Teams client to bot handler communication
a2 – Static UI content and React to extension app communication
b – Extension app to SAP BTP and Microsoft Graph communication
c – Notification handling from SAP SuccessFactors to Microsoft Teams client
a1 – Communication between Microsoft Teams and the bot handler of the extension application is secured by default when using the Azure Bot Service. Data requests to Microsoft Graph and SAP SuccessFactors are never done from the Microsoft Teams client itself, but always from the extension application (see b) and only results are delivered back to the client via the Azure Bot Service.
a2 – Requests for static UI content of the React component (task module) are not secured, as they do not contain any confidential content. If data needs to be displayed in or actions are triggered from the React component, a dedicated API provided by the extension application is called. This API only processes requests of valid Azure Active Directory users. The extension application then triggers the requests to Microsoft Graph and the SAP environment and only returns the result back to the React component. No direct calls are ever sent from your React component to Microsoft Graph or SAP.
b – No matter if a request is initiated by the bot handler or via the API used by the React component, all calls from the extension application to the SAP Cloud Integration and SAP SuccessFactors environment are secured by the concept of Principal Propagation. In case a matching user identity in the target environment is missing, the request fails. Same applies for missing privileges.
c – The backward communication between SAP SuccessFactors and SAP Cloud Integration (for sending notifications) is secured by client credentials of a Process Integration Runtime instance. The communication from SAP Cloud Integration to the corresponding notification endpoint of your extension application is secured by an XSUAA instance. Finally, the Azure Bot Service handles secure forwarding of notifications between your extension application and your Microsoft Teams client.
Microsoft Graph API access
To access Microsoft Graph when using a custom React component (e.g., in a task module or tab), the initial token (obtained from the authenticated user context) can be sent to the token endpoint of Azure Active Directory using the On-Behalf-Of flow (click here). Azure Active Directory will return a valid application access token, which can be used to call Microsoft Graph. The desired scopes can be defined in the application registration of your extension application.
In scenarios including the bot handler (e.g., chat bot or messaging extension), the so-called OAuth connection feature of the Azure Bot Service can be used, allowing a simplified exchange of the initial token (of an authenticated user) for the same application access token including the required Microsoft Graph scopes.
|Get a Microsoft Graph token using the initial token of an authenticated user
(extracted from the session context in the React component)File: /server/services/AuthClient.js (click here)
Hint: OAuth connections of the Azure Bot Service provide a similar functionality for scenarios including the bot handler. No manual call to the Azure Active Directory token endpoint is required in this case to obtain the application access token.
SAP SuccessFactors access
1) In case of a custom React component, the initial token (taken from the authenticated user context) can again be sent to the token endpoint of your Active Directory using the On-Behalf-Of flow. In the SAP SuccessFactors case, the Active Directory returns an application access token including a custom scope called access_as_user. This scope is also defined in the application registration of your extension application.
In scenarios including the bot handler (e.g., chat bot or messaging extension), another OAuth connection of the Azure Bot Service can be used, allowing a simplified exchange of the initial token (of an authenticated user) for the same application access token.
2) The application access token can now be used in another call to the Active Directory token endpoint, where it is exchanged for a SAML assertion usable for access to your SAP BTP environment. This is possible due to a trust configuration between your Active Directory and SAP BTP landscape.
3) Using this trust relationship, the SAML Assertion can be exchanged for SAP BTP access token. This happens by sending the SAML Assertion to the respective XSUAA endpoint. Thanks to the role collection mapping (based on the the propagated user and his Active Directory group assignment) the integration flows provided by SAP Cloud Integration can now be called using the access token issued by XSUAA.
4) The last step of Principal Propagation between Microsoft Teams and SAP SuccessFactors is handled by SAP Cloud Integration itself. Therefore, in SAP SuccessFactors, an OAuth client with the respective key of your SAP BTP subaccount has to be registered. This allows the usage of Principal Propagation between SAP Cloud Integration (SAP BTP) and SAP SuccessFactors without any further coding.
Get an access token for SAP BTP using the initial token of an authenticated user
File: /server/services/AuthClient.js (click here)
Hint: The method is called with an existing application access token in case of bot handler scenarios. The bot handler uses the OAuth connection feature of Azure Bot Service to get the respective application access token. No manual call of the Azure Active Directory token endpoint is required in this case.
As this has been a lot of information on various security aspects, I highly recommend, you always check back on these explanations during the upcoming blog posts. More information on the Principal Propagation approach used, can also be found in the following blog posts.
- Microsoft Teams to SAP Cloud Integration (click here)
- SAP Cloud Integration to SAP SuccessFactors (click here)
The last puzzle piece of the architecture worth highlighting, is the notification endpoint of your Microsoft Teams extension application. As this endpoint must only be called by SAP Cloud Integration (once a new notification is available), it is secured by a Bearer authentication strategy for Passport. This strategy is relying on an XSUAA instance (apiaccess) bound to your extension application.
The strategy ensures that only requests providing the correct XSUAA client credentials may access the notification endpoint of your extension application. The client credentials are stored in SAP Cloud Integration and can be used by your integration flows once a notification needs to forwarded to your Microsoft Teams extension application.
The upfront communication of notifications between SAP SuccessFactors and SAP Cloud Integration is again secured by client credentials. As SAP Cloud Integration offers a dedicated service instance for API access (Process Integration Runtime), you can make use of respective service key credentials. These are stored in the Intelligent Services Center on the SAP SuccessFactors side.
All in all, this ensures a secure forwarding of notifications from SAP SuccessFactors to SAP Cloud Integration and another secure interaction between SAP Cloud Integration and the notification endpoint of your Microsoft Teams extension application. The final notification transmission to your Microsoft Teams client is using the Azure Bot Service channel which is secured by default.
Wow, that’s it for the architecture and security part! Don’t worry if you only understood half of today’s blog post. If you’re new to authorizations and security related topics, this must have been quite overwhelming. From the next blog post onward, you will setup the described architecture yourself. Things will become much clearer once you’ve done the required configurations in your system. Just make sure you’re always getting back to this part of the blog post series once you’re starting a new technical chapter. This will help you to get an understanding of the architecture part you’re going to set up next.