
This brief is to showcase how to use dynamic_dest routes with SAP Build Work Zone, standard edition service (a managed approuter) to run SAP BTP destinations defined on a BTP sub-account level. Long story short. A community fellow donny.xu had asked me the following question. Beyond the technical aspects involved, dynamic_dest routes offer a simple solution to the very conundrum of how to test [complex] destinations [w/o the principal user propagation] without writing a single line of code... I shall discuss:
![]() |
https://<tenant>.launchpad.cfapps.<region>.hana.ondemand.com/dynamic_dest/<dest_name>/<api_endpoint>;
You can call an OAuth2-protected remote system/API and propagate a user ID to the remote system by using the OAuth2SAMLBearerAssertion authentication type. The Destination service provides functionality for automatic token retrieval and caching, by automating the construction and sending of the SAML assertion. This simplifies application development, leaving you with only constructing the request to the remote system by providing the token, which is fetched for you by the Destination service. For more information, see User Propagation via SAML 2.0 Bearer Assertion Flow.
https://<tenant>.launchpad.cfapps.<region>.hana.ondemand.com/dynamic_dest/S4HC-Product/$metadata
https://<tenant>.launchpad.cfapps.<region>.hana.ondemand.com/dynamic_dest/QUOVADIS-ISVENG-JWT/A_Sale...
https://ateam.launchpad.cfapps.sap.hana.ondemand.com/dynamic_dest/Quovadis-SAP-JWT/User?$top=1&$form...
https://<tenant>.launchpad.cfapps.<region>.hana.ondemand.com/dynamic_dest/ateam-partnereng/stories
dynamic_dest with SAP Build Work Zone, standard edition
if userIdSource property is set to email then
else
|
Nowadays, the kubernetes-managed, containerised workloads are becoming increasingly popular, almost ubiquitous. With SAP BTP, Kyma runtime's API rule CRD it is fairly easy to securely expose micro-services and their endpoints to the external world. As security is paramount, an API rule CRD can offer a number of access strategies to help restrict access to exposed endpoints. For the sake of this brief l opted to using the JWT access strategy as a way to protect an API rule endpoint(s) from unsolicited access. Good to know:
|
apiVersion: gateway.kyma-project.io/v1beta1
kind: APIRule
metadata:
name: "{{ .Values.services.srv.name }}-{{ .Release.Namespace }}"
spec:
gateway: {{ .Values.gateway }}
host: "{{ .Values.services.srv.name }}-{{ .Release.Namespace }}.{{ .Values.clusterDomain }}"
rules:
- accessStrategies:
- config:
jwks_urls:
- https://<tenant>.authentication.<region>.hana.ondemand.com/token_keys
trusted_issuers:
- https://<tenant>.authentication.<region>.hana.ondemand.com/oauth/token
required_scope:
- openid
handler: jwt
methods:
- GET
- PUT
- DELETE
- POST
- PATCH
- HEAD
path: /.*
service:
name: {{ .Values.services.srv.name }}
port: {{ .Values.services.srv.port }}
a destination definition towards to a kyma API rule
https://<tenant>.launchpad.cfapps.<region>.hana.ondemand.com/dynamic_dest/poster_dest/
To allow an application to call another application, passing the user context, and fetch resources, the caller application must pass an access token. In this authorization flow, the initial user token is passed to the OAuth server as input data. This process is performed automatically by the Destination service, which helps simplifying the application development: You only have to construct the right request to the target URL, by using the outcome (another access token) of the service-side automation.
Let's take the above words for granted and build such a destination definition. We shall use an instance of XSUAA service acting as an OIDC provider... OAuth JWT Bearer Authentication And bingo! This works as advertised! (more details in the appendix section below....) https://<tenant>.launchpad.cfapps.<region>.hana.ondemand.com/dynamic_dest/quovadis-anywhere/?host=to... ![]() |
{
"alg": "RS256",
"jku": "https://<tenant>.authentication.<region>.hana.ondemand.com/token_keys",
"kid": "<kid>",
"typ": "JWT",
"jid": "<jid>"
}.{
"jti": "<jti>",
"ext_attr": {
"enhancer": "XSUAA",
"subaccountid": "<subaccountid>",
"zdn": "<zdn>"
},
"xs.system.attributes": {
"xs.rolecollections": [
"Subaccount Service Administrator",
"SAP HANA Cloud Administrator",
"Subscription Management Dashboard Administrator",
"Subaccount Administrator",
"Launchpad_Admin",
"faas-faas_hc-faas"
]
},
"given_name": "Foo",
"xs.user.attributes": {},
"family_name": "Bar",
"sub": "<sub>",
"scope": [
"openid",
"faas-faas!t6455.Admin",
"faas-faas!t6455.User",
"uaa.user"
],
"client_id": "sb-faas-faas!t6455",
"cid": "sb-faas-faas!t6455",
"azp": "sb-faas-faas!t6455",
"grant_type": "authorization_code",
"user_id": "<user_id>",
"origin": "ldap",
"user_name": "foo.bar@sap.com",
"email": "foo.bat@sap.com",
"auth_time": <auth_time>,
"rev_sig": "<rev_sig>",
"iat": <iat>,
"exp": <exp>,
"iss": "https://<tenant>.authentication.<region>.hana.ondemand.com/oauth/token",
"zid": "<zid>",
"aud": [
"uaa",
"openid",
"faas-faas!t6455",
"sb-faas-faas!t6455"
]
}.[Signature]
{
"owner": {
"SubaccountId": "<SubaccountId>",
"InstanceId": null
},
"destinationConfiguration": {
"Name": "quovadis-anywhere",
"Type": "HTTP",
"URL": "https://poster.<business_domain>.com/",
"Authentication": "OAuth2JWTBearer",
"ProxyType": "Internet",
"tokenServiceURLType": "Dedicated",
"HTML5.DynamicDestination": "true",
"clientId": "<clientId>",
"Description": "poster",
"scope": "openid",
"HTML5.Timeout": "60000",
"clientSecret": "<clientSecret>",
"tokenServiceURL": "https://<tenant>.authentication.<region>.hana.ondemand.com/oauth/token"
},
"authTokens": [
{
"type": "bearer",
"value": "eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vYXRlYW0uYXV0aGVudGljYXRpb24uc2FwLmhhbmEub25kZW1hbmQuY29tJN5W0TMNG32nVayH5yMwKHClhH3OW5Asx61KSE1hTu4HpwgDp4a-P-HG3Fw0XQmQIUe_m8YuQ0s6WFQHsbPlLLaINxfPL-Q",
"http_header": {
"key": "Authorization",
"value": "Bearer eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vYXRlYW0uYXV0aGVudGljYXRpb24uc2FwLmhhbmEub25kZW1hbmQuY29tLJN5W0TMNG32nVayH5yMwKHClhH3OW5Asx61KSE1hTu4HpwgDp4a-P-HG3Fw0XQmQIUe_m8YuQ0s6WFQHsbPlLLaINxfPL-Q"
},
"expires_in": "42389",
"scope": "openid"
}
]
}
{
"alg": "RS256",
"jku": "https://<tenant>.authentication.<region>.hana.ondemand.com/token_keys",
"kid": "<kid>",
"typ": "JWT",
"jid": "<jid>"
}.{
"jti": "<jti>",
"ext_attr": {
"enhancer": "XSUAA",
"subaccountid": "<subaccountid>",
"zdn": "<zdn>"
},
"xs.system.attributes": {
"xs.rolecollections": [
"Subaccount Service Administrator",
"SAP HANA Cloud Administrator",
"Subscription Management Dashboard Administrator",
"Subaccount Administrator",
"Launchpad_Admin",
"faas-faas_hc-faas"
]
},
"given_name": "Foo",
"xs.user.attributes": {},
"family_name": "Bar",
"sub": "<sub>",
"scope": [
"openid"
],
"client_id": "<client_id>",
"cid": "<cid>",
"azp": "<azp>",
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"user_id": "<user_id>",
"origin": "ldap",
"user_name": "foo.bar@sap.com",
"email": "foo.bar@sap.com",
"rev_sig": "<rev_sig>",
"iat": <iat>,
"exp": <exp>,
"iss": "https://<tenant>.authentication.<region>.hana.ondemand.com/oauth/token",
"zid": "<zid>",
"aud": [
"openid",
"<client_id>"
]
}.[Signature]
https://<tenant>.authentication.<region>.hana.ondemand.com/support.jsp
XS_APPLICATIONUSER
page so you can fetch a short-lived JWT token of the currently logged BTP user, as follows:https://<tenant>.authentication.<region>.hana.ondemand.com/config?action=xs_appuser
XS_APPLICATIONUSER:
Type: JWT
Metadata: https://<tenant>.authentication.<region>.hana.ondemand.com/sap/trust/jwt
Test SQL:
-- start sql
SET 'XS_APPLICATIONUSER' = 'eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vYXRlYW0uYXV0aGVudGljYXRpb24uc2FwLmhhbmEub25kZW1hbmQuY29tFk5w-ug';
SELECT key,value from M_SESSION_CONTEXT WHERE KEY LIKE 'XS_%' AND CONNECTION_ID = CURRENT_CONNECTION;
-- end sql
Token Validity: 5 minutes
Details
SAP note: 2470084
sap
.You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
25 | |
24 | |
17 | |
14 | |
10 | |
9 | |
9 | |
7 | |
7 | |
7 |