Note: This blog post is the sixth part of a tutorial series. If you arrived here without reading the first part, please do so before you continue, and then come back here again. Part I explains the key concepts and technology standards for principal propagation in the context of calling a simple Web Service deployed on SAP Business Technology Platform (BTP) on behalf of the authenticated user from Azure Active Directory (AAD). Parts IIIIIIV and V extend this scenario step by step by adding on-premise connectivity, Microsoft Teams integration and API management to it. I do recommend looking at these parts as well to get an in-depth understanding of all bits and pieces, but they are not a prerequisite to implement the solution in this part of the blog series. Part VI (this blog post) starts looking at the reverse direction for propagating the authenticated user (aka “principal”) from SAP to Azure.

Don’t miss SAP TechEd 2022 and check out session XP106 (Single Sign-On and Principal Propagation in Multi-Cloud Environments), where Marko Sommer and I will focus on this scenario and show a live demo.

Microsoft Graph

In the previous parts of this blog series, data has always been retrieved from an SAP-provided service. Part I started the journey with a simple Web Service implemented as a Java servlet deployed on the SAP Business Technology Platform (BTP) Cloud Foundry (CF) environment. From part II onwards, the service is hosted on an SAP Gateway system. With this part, we are turning the data and token exchange flow for propagating the authenticated user (principal) into the opposite direction: The user logs on to a web application on BTP which accesses data on behalf of this user from Microsoft Cloud service resources.

With Microsoft Graph, applications can leverage the rich data set from Microsoft 365 services such as Outlook, OneDrive, Teams and others. Instead of interacting with these services through different Software Development Kits (SDKs), Application Programming Interfaces (APIs), security, messaging and data formats, Microsoft Graph offers a centralized, consistent, RESTful API to access this data. The Microsoft Graph service directs the calls to the right source to free the developer from understanding where exactly the data lives. Graph also aggregates calls for efficiency and performance, and allows the developer to easily traverse the graph of data. This way, it’s easy to build an application that – for example – based on a security alert traverses the graph to see which users might be affected, and for each user, which devices and documents might be affected – thus making it easy to connect data from across many services to enable faster response to threats and asset protection. The Operational Purchaser Chatbot for SAP S/4HANA is an example of an SAP business application using Graph to integrate with Microsoft’s collaboration services. It provides a convenient way to initiate an ad-hoc collaboration via Microsoft Teams to reach out to a supplier via the contact data associated with them and create calendar events in Outlook.

This blog post looks at a similar scenario which reads the SAP-authenticated user’s calendar events from Outlook. To do so, the web application running on BTP requires an OAuth access token formatted as a JSON Web Token (JWT) with the following content:

  • The token must be issued by Azure AD for the signed-in user and contain information such as the user’s unique identifier
  • It must contain the permissions (aka scopes) that the application needs to access the data in Microsoft Graph on behalf of the user. Microsoft Graph supports two types: Delegated and application permissions. Delegated permissions require the user or an administrator consent to the permissions that the application requests to make Microsoft Graph calls on behalf of the signed-in user. Application permissions are used by application such as background services or daemons that run without a signed-in user context and use their own identity, also known as a service principal. For the scenario in this blog post, delegated permissions are required to retrieve the user’s calendar events.
  • Information for whom the access token is issued for, also referred as audience. In this scenario, the token’s audience must be set to the URL that uniquely identifies the Graph service (application) in Azure AD. The Graph service checks that the audience element’s value in the token is https://graph.microsoft.com. Otherwise, the request will be rejected because the token is considered to be used for a different service.

Scenario overview

The starting point in this scenario is the user’s access token issued by the SAP Cloud Identity tenant’s authentication service (IAS), indicated as AT(IAS)APP in returned by step 2 in figure 1 below and following the notation <token type>(<issuer>)<audience>. The complete token exchange is orchestrated by the OAuth 2.0 and OpenID Connect (OIDC) authorization and authentication frameworks and their respective token types, which are access tokens (AT), refresh tokens (RT), and identity tokens (ID). Thus, AT(IAS)IAS is an access token, issued by the IAS tenant’s OAuth 2.0 authorization server, with an audience set to the IAS tenant’s client ID. All tokens except for refresh tokens are formatted as JWTs. Compared to the token exchange in the previous parts of this blog series (see part IInteroperability and standards, for more details), SAML 2.0 – or more precisely the SAML assertion as an OAuth 2.0 authorization grant defined in section 2.1 of RFC 7522 – is no longer used in this scenario. Instead of transforming between different token formats (JWT to SAML and back to JWT), this scenario only uses JWTs for the token exchange. It is important to note that for this token exchange no direct trust relationship between the application on BTP and Azure AD is required. The application only has a trust relationship to the IAS tenant, and the IAS tenant maintains the trust relationship to the Azure AD tenant (and vice versa).

All authentication requests for the business application on BTP are forwarded by the IAS tenant to the Azure AD tenant which is configured as a corporate identity provider (IdP) in IAS. IAS acts as a proxy and delegates authentication to Azure AD in the role of the relying party to the corporate identity provider. The IAS tenant therefore requires an application registration in Azure AD. The same applies to the business application on BTP which is also registered as an application in Azure AD.

Figure 1: Authentication and token exchange flows

Let’s have a closer look at the steps in figure 1:

  1. The user accesses the BTP business application’s app router URL on BTP, which serves as a single point of entry for an application running in the CF environment. This Node.js based component serves static content, authenticates users as a service provider, rewrites URLs, and can proxy requests to other micro services (such as the Java-based Calendar Service in this demo business application) while forwarding the user infomation obtained from the identity provider. In this scenario, the app router delegates authentication to the IAS tenant using OIDC. It starts the authentication process by redirecting the user’ browser to the IAS tenant’s OAuth server authorization endpoint at https://<IAS tenant name>.accounts.ondemand.com/oauth2/authorize and sending an OAuth authorization request using the authorization code grant type with the request parameters defined in RFC 6749, section 4.1.1. Those include the application’s endpoint (redirect_uri) to where IAS will send the authorization code response to after completing step 4. It further contains the application’s client ID generated from the application’s binding to the BTP identity services.
  2. Because the user is not yet authenticated at the IAS tenant, the user’s browser is redirected to the IAS tenant’s single sign-on (SSO) endpoint at https://<IAS tenant name>.accounts.ondemand.com/saml2/idp/sso.
  3. The business application is configured in IAS to pass all authentication requests to Azure AD as its corporate IdP. Therefore, IAS sends an OAuth authorization request to the Azure AD tenant’s OAuth authorization endpoint at https://login.microsoftonline.com/<AAD Tenant ID>/oauth2/v2.0/authorize using the authorization code grant flow. This time, the redirect_uri parameter instructs Azure AD to send the authorization code response back to IAS at https://<IAS tenant name>.accounts.ondemand.com/oauth2/callback. This callback URI must be configured in Azure AD for the IAS tenant’s application registration. Otherwise, Azure AD will reject the authorization request.
  4. The user gets prompted by Azure AD to enter the credentials. Upon successful authentication, Azure AD sends the authorization code to IAS by redirecting the user’s web browser to the URI specified in the previous request (https://<IAS tenant name>.accounts.ondemand.com/oauth2/callback?code=…).
  5. IAS receives the authorization code and sends an access token request to Azure AD’s token endpoint at https://login.microsoftonline.com/<AAD Tenant ID>/oauth2/v2.0/token according to RFC 6749 (section 4.1.3) by redeeming the code in the code parameter. Azure AD issues an access token and refresh token (RT(AAD)IAS which is cached for later use in step 8) for the authenticated user with an audience set to the IAS tenant’s OIDC name. Figure 2 shows an example for AT(AAD)IAS:

Figure 2: AT(AAD)IAS returned to IAS tenant in step 5

    • iss(uer) matches the value of the issuer configured for the corporate IdP in IAS (https://login.microsoftonline.com/<AAD tenant ID>/v2.0)
    • aud(ience) is the application (client ID) of the application registration for IAS in AAD
    • sc(o)p(e) is the default custom scope configured for the IAS application registration in AAD which is also referred in the OIDC corporate IdP configuration in IAS
    • sub(ject) is a pairwise unique identifier of the user in AAD in the context of the IAS application. It changes for each application in the AAD tenant.
    • o(bject)id is the Azure AD tenant-wide unique identifier of the user. Other than the sub(ject) user identifier, the object id remains the same across all applications in the tenant. The user’s object id is used when making queries to Microsoft online services, such as the Microsoft Graph, as done in step 10 in this scenario.

IAS also generates an access token AT(IAS)APP (see figure 3), identity token ID(IAS)APP, and refresh token RT(IAS)APP which are sent back to the application in the response from the previous request in step 4.

Figure 3: AT(IAS)APP returned to business application in the response of step 4

    • iss(uer) is the OIDC name of the IAS tenant (https://<IAS tenant name>.accounts.ondemand.com)
    • aud(ience) is the client ID of the BTP business application in the IAS tenant
    • sub(ject) is taken from the original AT(AAD)IAS token and is the same pairwise unique identifier of the user in AAD in the context of the IAS application.
  1. The BTP business application requests a client assertion (see the OAuth Client Credentials info box below for more details) from the IAS tenant to use it in the subsequent requests for the token exchange via the IAS tenant’s OIDC proxy. The client application sends a token request to the IAS tenant’s token endpoint by passing the parameters grant_type with value client_credentials and resource with value urn:sap:identity:corporateidp as body parameters. The POST request is authenticated with the client ID and secret of the business application in IAS. The client assertion from IAS takes the form of a signed JWT as shown in figure 4 that proofs the application’s identity to AAD when requesting tokens via the IAS corporate IdP OIDC proxy.

Figure 4: Client assertion AT(IAS)AAD

    • iss(uer) is the OIDC name of the IAS tenant (https://<IAS tenant name>.accounts.ondemand.com)
    • aud(ience) is the Azure AD tenant (https://login.microsoftonline.com/<AAD tenant ID>/v2.0)
    • sub(ject) is the client ID of the business application in the IAS tenant.

To ensure that Azure AD accepts this assertion as a valid client credential, Azure AD must trust the IAS tenant as an external issuer (IdP) of the client assertion. This trust relationship is maintained as a federated identity credential (IASTenantFederation in figure 1) in the application registrations for the BTP business application and IAS tenant in Azure AD.

  1. The business application exchanges the IAS-issued ID token ID(IAS)APP into an Azure AD-issued access token AT(AAD)APP via the IAS tenant’s OIDC proxy token exchange endpoint (https://<IAS tenant name>.accounts.ondemand.com/oauth2/exchange/corporateidp). The POST request uses the assertion parameter to pass the base64-encoded IAS ID token of the user.
  2. IAS token service sends a refresh token request using RT(AAD)IAS cached in step 5 to obtain a new access token AT(AAD)APP for the business application, shown in figure 5:

Figure 5: Business application access token AT(AAD)APP

    • iss(uer) is the OIDC name of the Azure AD tenant (https://login.microsoftonline.com/<AAD tenant ID>/v2.0)
    • aud(ience) is the client ID of the business application in the Azure AD
    • sub(ject) is the pairwise unique identifier of the user in AAD in the context of the business application. It is different from the user’s sub(ject) claim in figure 2 because it changes for each application in the AAD tenant.
  1. The business application uses the Azure AD On-behalf-Of (ObO) flow for requesting the access token AT(AAD)GRAPH required to call Microsoft Graph API on behalf of the logged-in user. This POST request to the Azure AD tenant’s token endpoint uses the following body parameters:
    • assertion: The user’s access token for the application obtained in the previous step (AT(AAD)APP)
    • grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer
    • client_assertion: Client assertion AT(IAS)AAD obtained in step 6 for authenticating the business application as an authorized client to Azure AD
    • client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    • requested_token_use: on_behalf_of
    • scope: https://graph.microsoft.com/.default

The scope parameter instructs Azure AD to generate a new token suitable for calling the Graph API on behalf of the authenticated user as shown in figure 6:


Figure 6: Graph API access token AT(AAD)GRAPH

    • iss(uer) is the Azure AD tenant (https://sts.windows.net/<AAD tenant ID>/). This value is different from previous Azure AD-issued tokens for the IAS tenant application (see figure 2) and BTP appplication (see figure 5). The Graph API is an Microsoft-owned application in Azure AD which has a different version (“1.0“, see ver(sion) claim in figure 6) than the two customer-owned applications (“2.0“). More details on the two token formats in Azure AD and the differences between version 1 and 2 can be found here.
    • aud(ience) is set to the Graph API’s application ID URI in Azure AD (https://graph.microsoft.com)
    • sub(ject) is the pairwise unique identifier of the user in AAD in the context of the Graph API (application). It is different from the user’s sub(ject) claim in figures 2 and 5 because it changes for each application in the AAD tenant.
    • sc(o)p(e) contains the delegated permission Calendars.Read to allow the business application making the Microsoft Graph call on behalf of the signed-in user and access her calendar events from Outlook.
  1. Finally, the business application calls the Microsoft Graph API at https://graph.microsoft.com/v1.0/me/calendar/events to read the signed-in user’s calendar events. This HTTP GET request uses the authorization header to send the user’s AT(AAD)GRAPH Graph API token according to RFC 6750. The response (see figure 7) contains the Open Data Protocol (OData)-compliant calendar events of the user:

Figure 7: OData response payload from Graph API

The response payload starts with the @odata.context element containing the Azure AD tenant-wide unique user’s object ID (see oid claim in figures 2, 5 and 6) in the Graph API query URL. The value element holds an array of calendar events for this user.

OAuth Client Credentials
Using client ID and client secret is the most common method to authenticate a client application’s token request to an OAuth authorization server. From a security and administration perspective, this type of client credentials has some drawbacks: 

  • Similar to passwords, an OAuth client secret is a shared credential between both parties. It may be sent on every request using the HTTP authorization request header, or as form parameter in an HTTP POST request body. This bears the risk of leaking the secret, either by storing it in an unsafe storage location (e.g. file system, source control), or during transfer over the network from the client to the authorization server.
  • To reduce the risk of unauthorized access, some (but not all) OAuth authorization server enforce rotation of client secrets. In AAD, the maximum lifetime of a secret is two years. Regular rotation of a client secret on the server-side is somewhat straightforward, but the client needs to be informed about the change as well. To avoid unplanned downtimes, the authorization server may generate a new secret before the old one expires, and allows to use the old secret for a small period of time until the client is updated with the new secret. However, client secret rotation means more complexity on the client side, and additional administration overhead.

As an alternative to client secrets, RFC 7523, section 2.2, defines the use of JWTs (aka client assertion) as client credentials for client authentication. In short, the specification defines using a client_assertion parameter with any OAuth grant to authenticate the client, as long as the receiver trusts the issuer of the JWT. Thus, client assertions eliminate the risk of leaking secrets or having secrets expire. The client is in full control of the lifecycle of its credential which provides enough means to assert the client’s identity to the authorization server.

Preparation

Check out the code for the BTP application with

git clone https://github.com/raepple/azure-scp-principal-propagation.git
git checkout part6

If you haven’t already done so from your setup in part I, make sure you have the following tools installed on your local development environment:

Furthermore, access to the following cloud services is required:

  • A BTP enterprise account with Space Manager access. The BTP trial account used in part I of this blog series doesn’t include the Identity service of SAP BTP which is required in this part to bind an instance to the business application.
  • Administrator-level access to an Azure AD tenant to create and configure the application registrations. The Microsoft 365 E5 developer subscription that you may have created in part III of the blog series will work for this scenario.
  • Administrator-level access to an SAP Cloud Identity service tenant

Register the applications in Azure AD

The token exchange and OIDC proxy setup between the business application on BTP, IAS, and the Azure AD tenant, requires a trust relationship which is established by registering two applications in the Azure AD tenant (see figure 1):

  • “SAPIASTenant” represents the SAP Cloud Identity Service tenant
  • “SAPBTPApplication” represents the business application deployed on SAP BTP
Step Description Screenshot
1 Login to Azure Portal (e.g. with your Microsoft 365 E5 developer subscription’s admin account) and select Azure Active Directory from the portal menu.

Select App registrations from the left-side menu.

2 Click + New registration
3 Enter “SAPIASTenant” for the Name of the new application registration.

Select “Web” from the dropdown list in the Redirect URI section.

Enter your IAS tenant’s redirect URI in the Redirect URI section’s text field: https://<IAS tenant name>.accounts.ondemand.com/oauth2/callback. Replace <IAS tenant name> with your tenant’s name.

Click Register.

4 Copy the newly generated Application (client) ID to a temporary text file. You will need it in the next step for deploying the sample application.
5 Select Manifest from the navigation menu to edit the application registration’s manifest file.

Change the value for the fieldaccessTokenAcceptedVersion from null to 2.

Click Save.
6 Click on the breadcrumb naviation to return to the list of application registrations.
7 Click + New registration
8 Enter “SAPBTPGraphApp” for the Name of the new application registration.

Click Register.

9 Copy the newly generated Application (client) ID to a temporary text file. You will need it in the next step for deploying the sample application.
10 Select Manifest from the navigation menu to edit the application registration’s manifest file.Change the value for the fieldaccessTokenAcceptedVersion from null to 2

Click Save.

Deploy the sample application on SAP BTP

Step Description Screenshot
11 Open the file vars.yml from the BTP subdirectory of your Git repository’s local copy in an editor.
12 Change the following placeholder values: 

  • Line 5: Replace <ID> with a random number, e.g. 76543. This ID will be part of the application’s URL and must be unique within the application’s region.
  • Line 7: Replace <region> with your subaccount’s region, e.g. ap21
  • Line 9: Replace the value with the application (client) id copied in step 9
  • Line 11: Replace the value with the application (client) id copied in step 4

Save the changes.

13 Open the file manifest.json from the BTP/application/src/main/webapp subdirectory and change the placeholder values in line 57

  • Replace <ID> with the same random number chosen in the previous step
  • Replace <region> with your subaccount’s region, e.g. ap21

Save the changes.

14  

Open the file MainView.controller.js from the BTP/application/src/main/webapp/controller subdirectory and change the placeholder values in line 13:

Save the changes.

15 Open a command prompt and change to the BTP subdirectory

Run mvn clean package.

The build process should end with a BUILD SUCCESS message.

16 Login to your SAP BTP CF subaccount with the command

cf login -a https://api.cf.<region>.hana.ondemand.com

Replace <region> with your subaccount’s region, e.g. ap21.

Enter your subaccount administrator’s email and password and select your target org and space.

17 Create a new service instance of the SAP BTP identity service with the command 

cf create-service identity application ias-btpgraph
18 Create a new service instance of the SAP BTP destination service with the command 

cf create-service destination lite destination-btpgraph
19 Run the command

cf push –vars-file ./vars.yml

This will deploy the application’s components to your SAP BTP CF subaccount.

20 Login to the SAP BTP Cockpit and navigate to your CF subaccount.
21 Go to Cloud Foundry > Spaces in the navigation menu.

Click on the space selected for the deployment of the application.

22 Go to Services > Instances in the navigation menu.

Select the ias-btpgraph service instance from the list.

Click View Credentials.

23 Copy the value of the clientid element in line 2 to a temporary text file. This is the OAuth client ID of the business application in the IAS tenant. You will need this id in the next step to configure trust to your IAS tenant in Azure AD.

Click Close.

Configure trust to the IAS tenant in Azure AD

Trust to the IAS tenant is configured in Azure AD with a new federated identity credential. In addition, a client secret is required for the initial token exchange in step 5 of figure 1. Both credentials will be configured for the application registrations in the following step.

Step Description Screenshot
24 Go back to the Azure Portal from step 10.

Select Certificates & secrets from the navigation menu of the SAPBTPGraphApp application registration.

Switch to the tab Federated credentials.

Click Add credential.

25 Select Other Issuer from the Federated credential scenario dropdown list.
26 Enter the following values: 

  • Issuer: The OIDC name of the IAS tenant (https://<IAS tenant name>.accounts.ondemand.com)
  • Name: IASTenantFederation
  • Audience: The OIDC name of your Azure AD tenant (https://login.microsoftonline.com/<AAD tenant ID>/v2.0)

Click Add.

27 Navigate back to the App registrations with the breadcrumb navigation.
28 Select the SAPIASTenant app from the list.

Select Certificates & secrets from the menu and switch to the Client secrets tab.

Click + New client secret.

29 Enter “OIDCProxy” for the Description.

Click Add.

30 Click Copy to clipboard in the Value column and paste it to a temporary text file. You will need it later in the setup process.
31 Switch to the tab Federated credentials.

Click + Add credential.

32 Enter the following values: 

  • Issuer: The OIDC name of the IAS tenant (https://<IAS tenant name>.accounts.ondemand.com)
  • Name: IASTenantFederation
  • Audience: The OIDC name of your Azure AD tenant (https://login.microsoftonline.com/<AAD tenant ID>/v2.0)

Click Add.

Configure Graph API permissions and scopes in Azure AD

To request the Outlook calendar event on behalf of the user, the business application (SAPBTPGraphApp) requires the Graph API permission Calendars.Read. SAPBTPGraphApp also exposes the custom scope “token.exchange”. This scope is referred to as a (downstream) API permission for the SAPIASTenant application registration and required for steps 7 and 8 in figure 1. For the initial token request to Azure AD (see step 5 in figure 1 and figure 2), the SAPIASTenant application exposes the custom scope “ias.access“.

Step Description Screenshot
33 Go to Expose an API in the navigation menu.

Click + Add a scope.

34 Accept the default value for the Application ID URI.

Click Save and continue.

35 Enter “ias.access” for the new Scope name. Provide an Admin consent display name and description.

Click Add scope.

36 Copy the full-qualified URI of the new scope (api://<client id>/ias.access) from the clipboard to temporary text file. It will be used in a later setup step.
37 Click on the breadcrumb naviation to return to the list of application registrations.
38 Select the SAPBTPGraphApp application from the list. Choose API permissions from the navigation menu.

Click + Add a permission.

39 Click the Microsoft Graph tile.
40 Click the Delegated permissions tile.
41 Enter “Calendar” in the search text box.

From the search results, activate the checkbox for the Calendars.Read permission.

Click Add permissions.

42 Click Grant admin consent for <Azure AD tenant name> and confirm with Yes so that the user is not prompted to consent to the Graph permissions used by the application.
43 Navigate to Expose an API in the menu.

Click + Add a scope.

44 Accept the default value for the Application ID URI.

Click Save and continue.

45 Enter “token.exchange” for the new Scope name. Provide an Admin consent display name and description.

Click Add scope.

46 Click on the breadcrumb naviation to return to the list of application registrations.
47 Select the SAPIASTenant application from the list. Choose API permissions from the navigation menu.

Click + Add a permission.

48 Switch to the tab My APIs
49 Select the SAPBTPGraphApp from the list. Activate the checkbox for the token.exchange permission.

Click Add permissions.

50 Click Grant admin consent for <Azure AD tenant name> and confirm with Yes so that the user is not prompted to consent to the requested permissions of the SAPIASTenant application.

Setup the Corporate Identity Provider and OIDC Proxy in SAP Cloud Identity tenant

Step Description Screenshot
51 Login as an administrator to your SAP Cloud Identity service administration console at https://<IAS tenant name>.accounts.ondemand.com/admin
52 Go to Identity Providers > Corporate Identity Providers and click Create.

Enter a Display name (e.g. “Azure Active Directory”) and click Save.

53 Click on Identity Provider Type from the Trust settings of the new corporate identity provider.
54 Select OpenID Connect Compliant from the list. 

Click Save.

55 Click on OpenID Connect Configuration from the Trust settings of the new corporate identity provider.
56 Enter your Azure AD tenant’s OIDC Discovery URL (https://login.microsoftonline.com/<AAD tenant ID>/v2.0)

Click Load.

The Issuer field gets populated from the loaded Azure AD tenant’s OIDC metadata.

57 Enter the SAPIASTenant’s client ID in the Client ID field. In the Client Secret field, enter the value of the OIDCProxy secret copied in step 30.

Click Validate.

58 Verify a successful validation of the OIDC configuration.

Click OK.

59 Click + Add
60 Copy and paste the full-qualified URI of the SAPIASTenant application’s custom scope (api://<client id>/ias.access) copied in step 36 for the new scope.

Click Save.

61 Click + Add again and add the scope “email”.

Click Save.

62 Click Save.
63 Go to Applications & Resources > Applications

Select the application ias-btpgraph from the list which was created from the identity service binding.

Click OpenID Connect Configuration from the Single Sign-On settings.

64 In the Redirect URIs section, click Add.
65 Enter the business application’s OAuth 2.0 redirect URL, which is at https://approuter-btpgraph-<ID>.cfapps.<region>.hana.ondemand.com/login/callback.

Replace <ID> and <region> with the values you used in step 10.

Click Save.

66 In the Conditional Authentication settings of the application, click Conditional Authentication.
67 Select the Corporate Identity Provider created in step 52 from the dropdown list as the Default Authenticating Identity Provider for the ias-btpgraph application. This will forward all authentication requests from the business application to the Azure AD tenant.

Click Save.

Configure destinations in the SAP BTP subaccount

The application uses the SAP Cloud SDK to authenticate against the SAP BTP destination service and retrieve the following destinations into the application:

  • aadTokenEndpoint: Azure AD token endpoint at https://login.microsoftonline.com/<AAD tenant ID>/oauth2/v2.0/token
  • iasTokenEndpoint: SAP Cloud Identity service tenant’s token endpoint at https://<IAS tenant name>.accounts.ondemand.com/oauth2/token
  • iasTokenExchange: SAP Cloud Identity service’s token exchange service endpoint at https://<IAS tenant name>.accounts.ondemand.com/oauth2/exchange/corporateidp
Step Description Screenshot
68 Go back to the SAP BTP Cockpit and navigate to your CF subaccount. 

Select Connectivity > Destinations from the navigation menu.

Click New Destination.

69 Enter the following values for the first destination: 

  • Name: aadTokenEndpoint
  • Type: HTTP
  • Description: Azure AD Token Endpoint
  • URL: https://login.microsoftonline.com/<AAD tenant ID>/oauth2/v2.0/token (replace AAD tenant ID with your data)
  • Proxy Type: Internet
  • Authentication: NoAuthentication

Click Save.

70 Repeat steps 68 and 69 with following values for the second destination: 

  • Name: iasTokenEndpoint
  • Type: HTTP
  • Description: IAS Token Service
  • URLhttps://<IAS tenant name>.accounts.ondemand.com/oauth2/token (replace IAS tenant ID with your data)
  • Proxy Type: Internet
  • Authentication: NoAuthentication

Click Save.

71 Repeat steps 68 and 69 with following values for the third destination: 

  • Name: iasTokenExchange
  • Type: HTTP
  • Description: Token Exchange Endpoint
  • URLhttps://<IAS tenant name>.accounts.ondemand.com/oauth2/exchange/corporateidp (replace IAS tenant ID with your data)
  • Proxy Type: Internet
  • Authentication: NoAuthentication

Click Save.

Test the scenario

Step Description Screenshot
72 Open a new web browser (e.g. in a private window) and go to the URL of your business applications’s approuter at

https://approuter-btpgraph-<ID>.cfapps.<region>.hana.ondemand.com/

Replace <ID> and <region> with the same values from step 12.

Because the business application in the IAS tenant is configured to forward the authentication request to the corporate IdP, the user is prompted by the Azure AD tenant to enter their credentials.

Enter your test user’s email address and click Next.

73 Enter your user’s password and click Sign in.
74 As a logged-in user, you can see your calendar events listed by application in the UI5 frontend. At this time there may be no events found.
75 Open a new browser tab and login to the Outlook web interface at https://outlook.office.com/calendar/view/month 

You will be single signed-on with your test user.

Click New event.

76 Choose a title for the new event and click Save.
77 Go back to the previous browser tab and refresh the business application’s page (Ctrl+R). 

This time the application lists the new calendar event you’ve just created for the user.

By requesting the Graph API token as shown in figure 1, the application could retrieve the data on behalf of the IAS- and Azure AD-authenticated user.

78 To take a look behind the scenes, open the application’s debug page at

https://approuter-btpgraph-<ID>.cfapps.<region>.hana.ondemand.com/debug

This page lists the tokens in Base64-encoded format that are exchanged between BTP, IAS and Azure AD.

79 Copy the value of the Graph access token (last token in the list) and paste its value into a JWT debugger tool such as https://jwt.ms

Conclusion

With this part of the blog series you’ve successfully implemented principal propagation starting from the authenticated user in SAP BTP calling a service in the Microsoft Cloud, which is equally important than the opposite direction covered by the previous parts. A big thank you goes to the security product teams on the SAP- and Microsoft-side who worked hard in the last months to enable this scenario.

Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x