I recently came across this
tiny little piece of documentation from BTP help portal describing the user propagation between cloud froundry application in different subaccounts.
I want to give a try in my environment and I will summarize with the use cases that I am thinking of afterwards at the end of this post.
Big Picture
An
extract from the BTP documentation shows it is possible to achieve sso between cf applications running in different subaccounts.
My Environment
- Subaccount 1: Cloud Foudry on Azure AP20
- Subaccount 2: Cloud Foundry on AWS EU10
As you can see the subaccounts sit on different regions and different hyperscalers as well. They both authenticate by default Identity provider (SAP ID Service).
Set the Stage
- Subaccount 1 (AP20 Azure): we will deploy a simple mta app. We use this repo as a template project, with a few tweaks. This template project is a simple mta project with a standalone application router, xusaa and static frontend running in HTML Application Repository. More description can be found here.
git clone https://github.com/SAP-samples/multi-cloud-html5-apps-samples
cd multi-cloud-html5-apps-samples/standalone-approuter-html5-runtime-mta-hello-world
npm install
Changes on xs-security.json by added the allowed redirect urls at the near bottom, so it looks like this.
{
"xsappname": "html5_app_repo_router",
"tenant-mode": "dedicated",
"description": "Security profile of called application",
"scopes": [
{
"name": "uaa.user",
"description": "UAA"
}
],
"role-templates": [
{
"name": "Token_Exchange",
"description": "UAA",
"scope-references": [
"uaa.user"
]
}
],
"oauth2-configuration": {
"redirect-uris": [
"https://*.hana.ondemand.com/**"
]
}
}
Changes on the HTML5Model/index.html, indicating the subaccount it is running on.
<html>
<header>
<title>Welcome</title>
<meta charset="UTF-8">
</header>
<body>
Hi there. This is AP20 Azure.
</body>
</html>
Build the mta, login to CF AP20 and deploy the mta app
npm run build //mbt build
cf l -a https://api.cf.ap20.hana.ondemand.com //and choose your space
cf deploy mta_archives/standalone-hello-world_1.0.0.mtar //deploy
2. Subaccount 2 (EU10 AWS): We will deploy the same template project with the similar changes on xs-security.json
...
"oauth2-configuration": {
"redirect-uris": [
"https://*.hana.ondemand.com/**"
]
}
...
and index.html
<html>
<header>
<title>Welcome</title>
<meta charset="UTF-8">
</header>
<body>
Hi there. This is EU10 AWS.
</body>
</html>
build and deploy to EU10
npm run build //mbt build
cf l -a https://api.cf.eu10.hana.ondemand.com //and choose your space
cf deploy mta_archives/standalone-hello-world_1.0.0.mtar //deploy
Let's open the standalone app router url of subaccount 1 in a new browser session and login default IdP.
https://xxxx.cfapps.ap20.hana.ondemand.com
Then in the same browser session, open the app router url of subaccount 2,
https://xxxx.cfapps.eu10.hana.ondemand.com
it requests for login again, which means these two apps from individual subaccounts are not yet trusting each other. They are still issuing tokens individually.
What we expect is to the sso between them, which will be covered in the next steps.
Establish Trust Between subaccount 1 (AP20 Azure) and subaccount 2 (EU10 AWS)
Basically we need subaccount 2 to trust the identity token which was generated when the user authenticated in the idP in subaccount 1, and grant accessing to the resources in subaccount 2.
According to the documention, we need to assemble a xml metadata using this template which includes all the related information of subaccount 1 and create the trust configuration in subaccount 2.
The information of subaccount 1 includes the following in my case
- landscape domain: ap20.hana.ondemand.com
- subaccount id: xxxx of ap20
- subaccount alias: can be found in the metadata file of subaccount ap20
- subaccount certificate (public key): can be found by the "Download Trust" from ap20 cockpit destination page
Detailed steps are already
documented here.
Please note there is a "Create Shadow Users During Logon" checkbox which needs to be ticked in the creation of the Trust. We will see what happens with this user afterwards.
Create the OAuthSAMLBearerAssertion Destination in subaccount 1
The OAuthSAMLBearerAssertion destination is supposed to do all the hard work to interact with subaccount 2's xsuaa instance to get the subaccount 1 token verified.
We need to create a service key from xsuaa instance in subaccount 2 when we deployed the mta app. Then pop the clientid into "tokenServiceUser" and "clientKey" and secret into "tokenServicePassword".
audience value can be found from the metadata file of subaccount 2.
URL value is the app router url in subaccount 2 we deployed.
The destination is named as "eu10pp"
#clientKey=<< same value as tokenServiceUser >>
#tokenServicePassword=<< secret from the service key we created in xsuaa instance in subaccount 2 >>
#
#Thu Mar 17 00:22:49 UTC 2022
Type=HTTP
authnContextClassRef=urn\:oasis\:names\:tc\:SAML\:2.0\:ac\:classes\:PreviousSession
audience=https\://xxxx.authentication.eu10.hana.ondemand.com
Authentication=OAuth2SAMLBearerAssertion
Name=eu10pp
tokenServiceURL=https\://xxxx.authentication.eu10.hana.ondemand.com/oauth/token/alias/xxxx
ProxyType=Internet
URL=https\://xxxx.cfapps.eu10.hana.ondemand.com -- URL to the app router in subaccount 2
nameIdFormat=urn\:oasis\:names\:tc\:SAML\:1.1\:nameid-format\:emailAddress
tokenServiceURLType=Dedicated
tokenServiceUser=sb-html5_app_repo_router\!t121888 -- clientid from the service key we created in xsuaa instance in subaccount 2
Checking the connection of the destination once done.
Connection to "eu10pp" established. Response returned: "302: Found"
Consume the OAuthSAMLBearerAssertion Destination
Update the mta app in subaccount 1 to consume the OAuthSAMLBearerAssertion Destination we created.
In the code base of the app of the subaccount 1, update the router/xs-app.json and add a new route at the top.
...
{
"source": "^/forwardme/(.*)$",
"target": "/$1",
"destination": "eu10pp", --the new destination here
"authenticationType": "xsuaa",
"csrfProtection": false
},
...
and index.html, we add a link.
<html>
<header>
<title>Welcome</title>
<meta charset="UTF-8">
</header>
<body>
Hi there. This is AP20 Azure.
<a href="https://blogs.sap.com/forwardme/">Forward Me to EU10</a>
</body>
</html>
build and deploy again.
npm run build //mbt build
cf l -a https://api.cf.ap20.hana.ondemand.com //and choose your space
cf deploy mta_archives/standalone-hello-world_1.0.0.mtar //deploy
Test
I found my primary user does not work in testing this scenario and I suspect it is because the account is linked to SAP Universal ID service. - if anyone knows the reason please comment below.
So I registered a new user email in SAP ID service and added it to subaccount 1 from the cockpit.
One more thing to do is to enable "Create Shadow Users During Logon" for the default idP in subaccount 2.
Open the app router URL in the subaccount 1 in a new browser session, login with the new user just created.
https://xxxx.cfapps.ap20.hana.ondemand.com
Hi there. This is AP20 Azure. Forward Me to EU10
Press the link and it briefly touches the auth server of subaccount 2 then goes straight in and fetches the welcome page of subaccount 2 without asking for login again.
https://xxxx.cfapps.ap20.hana.ondemand.com/forwardme/index.html
Hi there. This is EU10 AWS.
Job done!
Checking back the Users in subaccount 2, we see shadow user created automatically.
Use Cases
There will be some cases when you have your primary subaccount clusters in one region, but some btp services may not be available in this region. So you have to operate multiple subaccounts across different regions and there comes the requirement to provision user identities in between.
There will be some other use cases when you want to extend and call apis from your subaccount to a SaaS application which you subscribes and runs in a different subaccount and region.
Another example is when SAP partners build the SaaS application on BTP and run in their own subaccounts, customer can consume from their own subaccount. The user onboarding will be very easy with the principal propogation set up like this.
------
Please leave your comments below for any thoughts or feedbacks.
I might try out configuring the other way around. Also will explore the role mapping between the subaccounts in the trust configuration later on.
Note: I don't think the scenario will work with managed router as my experiment failed with some sort of restriction on the redirect rules of the managed router. Will try again and update.