Note: This blog is the first part of a tutorial series. It describes principal propagation between an application front-end running on Microsoft Azure, calling a Web Service deployed to SAP Business Technology Platform (BTP). Part II of this blog series extends the scenario by propagating the Azure-authenticated user via BTP and SAP Cloud Connector to an SAP Gateway system. Part III adds a business application to the scenario by implementing a chatbot in Microsoft Teams with the Microsoft Bot Framework V4 SDK, SAP BTP Integration Suite, and Core Data Services in the SAP Gateway system. A live demo of this scenario is available on episode #31 of the great SAP on Azure Video podcast series (starting at min 23:30) from hobruche , goran-condric, and roboban. Part IV uses a "low-code" approach for implementing the chatbot of part III with Microsoft Power Platform, demonstrated in episode #40 of the SAP on Azure Video Podcast series. Part V looks at different aspects for production readiness, such as API management, monitoring and alerting (live demo available on episode #83 in the SAP on Azure video podcast series). Part VI turns the scenario into the opposite direction by propagating the SAP-authenticated user of a BTP business application to call the Microsoft Graph API and retrieve the user's Outlook events. Finally, part VII looks at principal propagation from Microsoft Power Platform to SAP in the context of making Remote Function Calls (RFCs) and using Business Application Programming Interfaces (BAPIs) with the Kerberos protocol. See episode #142 of the SAP on Azure video podcast series for a live demo of this scenario. Start reading the blog series here to learn more about the core concepts and technologies used in the scenario. Configurations made in part I will be reused in the other parts of this tutorial series. Enjoy! |
To securely propagate the principal across different platforms and clouds, interoperability at the communication protocol and security token format level are key to the security architecture of the solution. A central standard addressing this scenario for principal propagation is described in RFC 7522, the Security Assertion Markup Language (SAML) 2.0 Profile for OAuth 2.0 Client Authenticat.... This extension to the OAuth 2.0 framework combines the interoperable and mature security token format from the SAML 2.0 standard with a simple request/response protocol from OAuth 2.0. Essentially, it describes how a client (in this scenario the web application frontend) accessing an OAuth-protected resource (the backend service) can obtain an OAuth access token from an OAuth authorization server by presenting a valid SAML assertion as the authorization grant. In this process, the user is not required to approve the token issuance at the authorization server. Other authorization grants of the OAuth 2.0 framework such as the authorization code ask for the user's explicit permission to allow a client application to access resources on behalf of the user. Since we want to avoid any form of user action such as asking for credentials or user consent, RFC 7522 is the ideal candidate for this scenario.
Let's take closer look at RFC 7522 in action in a concrete multi-cloud scenario of a web application that has a frontend deployed as an App Service in Microsoft Azure. Data is managed by a backend service running in the Cloud Foundry environment of SAP Cloud Platform, as shown in figure 1 below.
Figure 1: Multi-cloud scenario
The end-to-end process of a user authenticating at the frontend and accessing her data in the backend which performs authorization checks for the logged-in user follows these steps:
Audience
which is associated with the Condition
element of the SAML assertion. It defines under which security conditions the assertion is valid, such as the earliest and latest time instant before it expires, who can consume the assertion, etc. The Audience
must match the SAML service provider (SP) value (or EntityID
) of the XSUAA service instance in the BTP subaccount.Recipient
which is associated with the Subject
element of the SAML assertion. It uniquely identifies the subject or user between the IDP (Azure AD) and SP (XSUAA) for whom the assertion has been issued, defines the format of the user identifier (e.g. an e-mail address). The Recipient
must match XSUAA service instance endpoint (URL) where the assertion is received.Subject
element in the SAML assertion, and contains additional information required by the backend service to perform authorization checks.The next section shows the detailed configuration steps in Azure and BTP to setup the scenario.
Step | Description | Screenshot |
---|---|---|
1 | Clone the repository with the sample code for the scenario using the web URL https://github.com/raepple/azure-scp-principal-propagation.git with your favourite IDE or command line tool. | |
2 | Change to the SCP/service subfolder in the cloned repository | |
3 | Login to your BTP subaccount. In the following steps we'll use a trial account on BTP with the command cf login -a https://api.cf.us10.hana.ondemand.com | |
4 | Create the XSUAA service instance for the backend service with the command cf create-service xsuaa application service-xsuaa -c ./xs-security.json | |
5 | Build the backend service with the command mvn clean package | |
6 | Edit the file manifest.yml and replace the string <your-trial-org-name> with the value of your BTP trial subaccount's org name, e.g. 98abcd76trial . This ensures a unique route to the service in the (trial) landscape. | |
7 | Deploy the backend service to your subaccount with the command cf push |
Step | Description | Screenshot |
---|---|---|
8 | Open the BTP Cockpit in your browser and login with your account admin. Navigate to your trial account and select Security - Roles from the left side navigation menu. Search for the "Viewer" role template in the list and click on the Create Role link to create a new role based on the template, | |
9 | Enter "ViewerAAD" as the new role name and click Next. Continue with the configuration of the role attributes, which were defined by the xs-security.json "Viewer" role template. In our scenario, the Source of each attribute is the identity provider that originally authenticated the user, so Azure AD. Enter the following source attribute mappings:
Click Next. | |
10 | Leave the Role Collection selection empty for now, click Next and then Finish.The assignment to the role collection will be done in the next steps. | |
11 | Select Security - Role Collections in the navigation menu, and click on New Role Collection | |
12 | Enter a name for the new Role Collection (e.g. "Application User"), click Save, and select the new Role Collection from the list. Click on Edit and select the newly created Role "ViewerAAD" from the "service" application in the dropdown list. Confirm the changes with Save. | |
13 | Go back to the subaccount level in the breadcrumb navigation and select Security - Trust Configuration from the navigation menu. Click on SAML Metadata to export your (trial) subaccount's service provider (SP) SAML metadata. Remember where the XML-file is saved - it is used later in Microsoft Azure AD to simplify the trust setup. | |
14 | Finally, have look up a few configuration settings from the service binding between the "service" app and the XSUAA instance. These settings are required later to successfully request an OAuth access token from Azure with the Azure AD-generated SAML assertion (step 5 in Figure 1). Select Spaces from the navigation menu and then your target (e.g. dev) space. In Services - Instances, select the "service-xsuaa" instance. | |
15 | Select service in the Bound Applications table. Click on Show sensitive data, and copy the values for the following binding properties, e.g. in a temporary text file:
|
Step | Description | Screenshot |
---|---|---|
16 | Login to the Azure Portal and select Azure Active Directory from the Azure Services. Select App registriations from the left-hand navigation and click on New registration | |
17 | Enter an name for the new app registration of the frontend web app (e.g. "Contoso Web App"). Also provide a Redirect URI which is required for the authentication process. For the purpose of this tutorial, just enter a any URL string starting with https:// Click on Register. | |
18 | Select Manage - Authentication and activate the checkbox for Access Tokens of the Implicit grant. This setting simplifies testing later in the setup process. Click Save. | |
19 | Select Manage - Certificates & secrets from the navigation menu and click + New client secret. Enter a description of the new client secret for the web app frontend registration, choose an expiration time, and click Add. | |
20 | Copy the newly generated secret in a text file for later use. | |
21 | Select Manage - Expose an API from the navigation menu and click + Add a scope. You'll be asked to set the Application ID URI for the frontend app registration. Accept the proposed default value by clicking Save and continue. | |
22 | Choose a name of the new scope (e.g. "scp.access") and allow Admins and users to consent. Enter the required display name and consent description, and click Add scope. | |
23 | Finally, copy the Application (client) ID of the new web app frontend application registration from the Overview page to a text file. This will be required later for configuration and testing purposes. | |
24 | Next, register the second app in Azure AD which represents the backend service in BTP for which the SAML assertion will be requested (step 4 in figure 1). Select Manage - Enterprise Applications from the Azure AD service navigation menu, and click + New application. | |
25 | Enter "SAP Cloud Platform" in the search box, and select the tile for "SAP Cloud Platform" in the search results. Next, enter a name for the new enterprise app, e.g. "SAP Cloud Platform <your trial account name>". Click Create. | |
26 | For the newly created Enterprise Application registration, select the tile "2. Set up single sign on" and select the method "SAML" | |
27 | Click Upload metadata file and select the file containing your BTP subaccount's SAML Service Provider metadata you've download in step 13. Click Add. | |
28 | Most of the fields in the Basic SAML Configuration are automatically populated by the uploaded metadata file, which greatly simplifies the trust setup between Azure AD and BTP. For the mandatory Sign on URL, enter the value you copied from the url field of the XSUAA service instance binding infomration in step 15. Do not save the settings yet! | |
29 | Next, change the Reply URL. The already existing value was taken from the SAML metadata file and is the Assertion Consumer Service URL for the SAML protocol response message of your BTP tenant-specific XSUAA service instance, However, for RFC 7522, the SAML assertion is sent to the OAuth token endpoint of your XSUAA service instance, which is almost the same URL as for the SAML protocol. Just replace "saml/SSO" with "oauth/token" in the existing URL. This ensures that the Recipient URL is set correctly in the generates SAML assertion by Azure AD. Click Save. | |
30 | Next, you will configure additional attributes of the user which will be federated between Azure AD and BTP. Click on the pencil symbol for User Attributes and Claims | |
31 | Select the Unique User Identifier (Name ID) from list and change the Source attribute to user.mail. This will use the user's email address in Azure AD as the login name (Name ID) of the subject in the generated SAML assertion. Using the email address is a best practice for a common user identifier when federating users across clouds and other platforms. Click Save. | |
32 | To demonstrate federation of user attributes in the scenario, click + Add new claim and enter country in the name field. Set http://schemas.xmlsoap.org/ws/2005/05/identity/claims as the Namespace. Select user.country for the Source attribute. Click Save. | |
33 | Navigate back to the Setup Single Sign-On with SAML settings and scroll down to the SAML Signing Certificate settings. Click the Download link for the Federation Metadata XML. The downloaded file will be used later to setup the trust relationship in BTP. Note: If there is no Download link yet, try to refresh the page. | |
34 | Navigate back to the App Registrations in the Azure AD service navigation menu. Select All Applications as the filter settings from the top of the list and select the application registered for the backend service in BTP (e.g. "SAP BTP <name of your trial account>"). | |
35 | Select Manage - Expose an API from the navigation menu, and click + Add a client application | |
36 | Enter the client ID copied in step 23 into the corresponding field. Also activate the checkbox for the Authorized scopes. This will authorize the web app frontend application to request a SAML assertion from Azure AD for the backend service application. Confirm with Add application. |
Step | Description | Screenshot |
---|---|---|
37 | In BTP Cockpit, navigate back to the (trial) subaccount level via the breadcromb naviagtion on the top, select Security - Trust Configuration from the navigation menu, and click New Trust Configuration | |
38 | Upload the metadata file you exported in step 33 and click on Parse. Enter a name for the new trust configuration (e.g. "Contoso Azure AD") and deactivate the checkbox Available for User Logon, because this IDP is only trusted for non-interactive backchannel SSO, and not for normal user login/SSO. Click Save. | |
39 | Configure the authorizations of a user you'll use for testing. Select the Security - Role Collections from the navigation menu. Look for the Role Collection "Application User" create in step 12 in the list. You can also filter the list by entering the Role Collection's name in the search box on the upper right corner. Click on the Role Collection Application User in the list. | |
40 | Select the tab "Users (0)". There are no users assigned to the role collection yet. Click Edit. | |
41 | In the ID and E-Mail entry fields, enter the e-mail address of the test user in your Azure AD tenant that you will use in the next step for testing. In the Identity Provider dropdown list, select the previously created Identity Provider for your Azure AD tenant. Click the "+" button to add the user. Click Save. |
Step | Description | Screenshot |
---|---|---|
42 | Click Import, select Upload File, and select the Postman Collection file Azure AD SCP Principal Propagation.postman_collection.json from the Postman folder in the GitHub repository. Then click Import. | |
43 | Open the context menu for the imported Collection (...) and select Edit | |
44 | Switch to the Variables tab and enter the values for the placeholders:
Click Reset All to update the current values. Click Update. | |
45 | Open the collection, select the first request, and click Send. | |
46 | Switch to the Console view in Postman, and copy the complete request URL | |
47 | Paste the URL in a Web Browser and send the request again. Login with your test user credentials in Azure AD. The browser will be redirected to a potentially unknown reply URL (e.g. https://webapp.contoso.com/auth). Copy the request parameter access_token from the URL. | |
48 | You may want to decode and inspect the access_token with a tool of your choice, e,g, jwt.io | |
49 | Open the second request in the Postman collection, switch to the Body tab of the request, and paste the value of the access token. This requests the SAML assertion for the Azure AD-authenticated user. Click Send | |
50 | Copy the access_token value from the response. This is the SAML assertion generated by Azure AD. To inspect the content of the SAML assertion, Base64-decode it with an (online) tool of your choice. | |
51 | Open the third request in the Postman collection, switch to the Body tab of the request, and paste the assertion as the value for the assertion key. | |
52 | Switch to the Authorization tab. The request will use Authentication Type Basic. Username is the clientid and password the clientsecret you obtained from the XSUAA service binding in step 15. Click Send. | |
53 | From the XSUAA response copy the access_token element. Again, you may want to inspect the token with a tool of your choice. | |
54 | Open the last request in the collection. This request calls the backend service in BTP and requires the access token from the above request. Select the Authorization tab and paste the access_token value into the Access Token field. Click Send. | |
55 | The response from BTP shows the propagated principal's name identifier and the additional user attributes which were successfully federated. The principal also obtained the required scopes ("Display") in BTP to call the backend service based on the Role Collection assignment. |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
6 | |
5 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 | |
3 |