SAP / cloud-sdk-js

Use the SAP Cloud SDK for JavaScript / TypeScript to reduce development effort when building applications on SAP Business Technology Platform that communicate with SAP solutions and services such as SAP S/4HANA Cloud, SAP SuccessFactors, and many others.
Apache License 2.0
162 stars 56 forks source link

How to create an inline destination with OAuth2SAML2BearerAssertion authentication ? #3904

Closed ptesny closed 1 year ago

ptesny commented 1 year ago

Is it at all possible ? if so, what the the names of the mandatory attributes and optional properties of a destination definition? For instance, I've noticed URL becomes 'url` etc; What about the keystore ? Would the inline definition pick the keystore by name on the BTP subaccount level ? etc...

tomfrenken commented 1 year ago

Hey @ptesny, when you refer to "creating" an inline destination, do you mean that this destination would be created in Cloud Foundry, or only locally?

For the latter this is possible, you can either create a destination object or even register a destination.

If you simply want to use an object, you can refer to the type definition of destinations in our API documentation. Alternatively, you can also register a destination, as described in our regular documentation.

However, using either of these options means you have to take care of authentication (e.g. adding tokens to the destinations) yourself, therefore we generally recommend using the destination service instead and creating destinations in your BTP cockpit.

tomfrenken commented 1 year ago

Perhaps you can go into more detail about what you are trying to achieve with this?

ptesny commented 1 year ago

@tomfrenken ; I have the destination definition given in a secret of one the SAP extensibility services (on k8s in my case not with CF but it is a minor detail); and I'd like to create a cloud-sdk consumable destination definition on-the-fly. Same way as it can be already done with a simple NoAuthentication destination definition with an url and forward token attribute?

ptesny commented 1 year ago

@tomfrenken , after some digging it does not look like it is feasible. Let me try to explain what happens when Cloud-sdk makes a call to a fetch and run a sub-account level OAuth2SAMLBearerAssertion destination.

2023-06-19T08:42:12.177023484Z destination:  {
2023-06-19T08:42:12.177178685Z   "originalProperties": {
2023-06-19T08:42:12.177210686Z     "owner": {
2023-06-19T08:42:12.177235686Z       "SubaccountId": "***********",
2023-06-19T08:42:12.177260286Z       "InstanceId": "***************"
2023-06-19T08:42:12.177283486Z     },
2023-06-19T08:42:12.177307687Z     "destinationConfiguration": {
2023-06-19T08:42:12.177332287Z       "Name": "Quovadis-SAP",
2023-06-19T08:42:12.177356987Z       "Type": "HTTP",
2023-06-19T08:42:12.177380787Z       "URL": "https://apihost.successfactors.eu/odata/v2",
2023-06-19T08:42:12.177405487Z       "Authentication": "OAuth2SAMLBearerAssertion",
2023-06-19T08:42:12.177448688Z       "ProxyType": "Internet",
2023-06-19T08:42:12.177473888Z       "KeyStorePassword": "**********",
2023-06-19T08:42:12.177497688Z       "tokenServiceURLType": "Dedicated",
2023-06-19T08:42:12.177520688Z       "audience": "www.successfactors.com",
2023-06-19T08:42:12.177545889Z       "Description": "Generic SFSF destination",
2023-06-19T08:42:12.177571989Z       "authnContextClassRef": "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession",
2023-06-19T08:42:12.177595289Z       "apiKey": "******************",
2023-06-19T08:42:12.177619289Z       "tokenServiceURL": "https://host.successfactors.eu/oauth/token",
2023-06-19T08:42:12.177643490Z       "HTML5.DynamicDestination": "true",
2023-06-19T08:42:12.177667390Z       "companyId": "*************",
2023-06-19T08:42:12.177691090Z       "clientKey": "****************",
2023-06-19T08:42:12.177716690Z       "KeyStoreLocation": "quovadis-sap.pfx",
2023-06-19T08:42:12.177740090Z       "nameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
2023-06-19T08:42:12.177763991Z       "HTML5.Timeout": "600000",
2023-06-19T08:42:12.177789391Z       "SystemUser": "*************"
2023-06-19T08:42:12.177814191Z     },
2023-06-19T08:42:12.177837791Z     "certificates": [
2023-06-19T08:42:12.177861191Z       {
2023-06-19T08:42:12.177885392Z         "Name": "quovadis-sap.pfx",
2023-06-19T08:42:12.177917892Z         "Content": "MIIJaQIBAzCCCS8GCSqGSIb3DQEHAaCCCSAEggkcMIIJGDCCA88GCSqGSIb3DQEHBqCCA8AwggO8AgEAMIIDtQYJKoZIhuLmsoF0w3oYj1xllxSC9hRneWzAxMCEwCQYFKw4DAhoFAAQUPTi8wCiDIYWXJdI0tqd2XLbXSnsECAnnFfE3b2EgAgIIAA==",
2023-06-19T08:42:12.177955592Z         "Type": "CERTIFICATE"
2023-06-19T08:42:12.177977292Z       }
2023-06-19T08:42:12.177998893Z     ],
2023-06-19T08:42:12.178021193Z     "authTokens": [
2023-06-19T08:42:12.178043593Z       {
2023-06-19T08:42:12.178065693Z         "type": "Bearer",
2023-06-19T08:42:12.178090293Z         "value": "eyJ0b2tlbkNvbnRlbnQiOnsiYXBpS2V5IjoiTmpFMU5EYzVObVE0TnprMVlUSm1OVGhrTVRKbFpHTm1abUZrWVEiLCJzZlByaWYVRDNFlPU0JrMGk0MTVOUGtBc1FFPSJ9",
2023-06-19T08:42:12.178476197Z         "http_header": {
2023-06-19T08:42:12.178520497Z           "key": "Authorization",
2023-06-19T08:42:12.178571698Z           "value": "Bearer eyJ0b2tlbkNvbnRlbnQiOnsiYXBpS2V5IjoiTmpFMU5EYzVObVE0TnprMVlUSm1OVGhrTVRKbFpHTm1abUZrWVEiLCJzZlByaW5VRDNFlPU0JrMGk0MTVOUGtBc1FFPSJ9"
2023-06-19T08:42:12.178596998Z         },
2023-06-19T08:42:12.178637698Z         "expires_in": "35681"
2023-06-19T08:42:12.178661998Z       }
2023-06-19T08:42:12.178685099Z     ]
2023-06-19T08:42:12.178708399Z   },
2023-06-19T08:42:12.178731299Z   "authTokens": [
2023-06-19T08:42:12.188419284Z     {
2023-06-19T08:42:12.188461384Z       "type": "Bearer",
2023-06-19T08:42:12.188490385Z       "value": "eyJ0b2tlbkNvbnRlbnQiOnsiYXBpS2V5IjoiTmpFMU5EYzVObVE0TnprMVlUSm1OVGhrTVRKbFpHTm1abUZrWVEiLCJzZlByaWYVRDNFlPU0JrMGk0MTVOUGtBc1FFPSJ9",
2023-06-19T08:42:12.188530185Z       "expiresIn": "35681",
2023-06-19T08:42:12.188556785Z       "error": null,
2023-06-19T08:42:12.188600486Z       "http_header": {
2023-06-19T08:42:12.188627886Z         "key": "Authorization",
2023-06-19T08:42:12.188653786Z         "value": "Bearer eyJ0b2tlbkNvbnRlbnQiOnsiYXBpS2V5IjoiTmpFMU5EYzVObVE0TnprMVlUSm1OVGhrTVRKbFpHTm1abUZrWVEiLCJzZlByaW5VRDNFlPU0JrMGk0MTVOUGtBc1FFPSJ9"
2023-06-19T08:42:12.188679386Z       }
2023-06-19T08:42:12.188705386Z     }
2023-06-19T08:42:12.188732187Z   ],
2023-06-19T08:42:12.188758787Z   "certificates": [
2023-06-19T08:42:12.188785487Z     {
2023-06-19T08:42:12.188812087Z       "name": "quovadis-sap.pfx",
2023-06-19T08:42:12.188884988Z       "content": "MIIJaQIBAzCCCS8GCSqGSIb3DQEHAaCCCSAEggkcMIIJGDCCA88GCSqGSIb3DQEHBqCCA8AwggO8AgEAMIIDtQYJKoZIhuLmsoF0w3oYj1xllxSC9hRneWzAxMCEwCQYFKw4DAhoFAAQUPTi8wCiDIYWXJdI0tqd2XLbXSnsECAnnFfE3b2EgAgIIAA==",
2023-06-19T08:42:12.188946589Z       "type": "CERTIFICATE"
2023-06-19T08:42:12.188975589Z     }
2023-06-19T08:42:12.189002889Z   ],
2023-06-19T08:42:12.189028989Z   "name": "Quovadis-SAP",
2023-06-19T08:42:12.189054790Z   "type": "HTTP",
2023-06-19T08:42:12.189082090Z   "url": "https://apihost.successfactors.eu/odata/v2",
2023-06-19T08:42:12.189109190Z   "authentication": "OAuth2SAMLBearerAssertion",
2023-06-19T08:42:12.189136090Z   "proxyType": "Internet",
2023-06-19T08:42:12.189162090Z   "keyStorePassword": "************",
2023-06-19T08:42:12.189186091Z   "tokenServiceUrl": "https://host.successfactors.eu/oauth/token",
2023-06-19T08:42:12.189211091Z   "keyStoreName": "quovadis-sap.pfx",
2023-06-19T08:42:12.189234791Z   "systemUser": "************",
2023-06-19T08:42:12.189257891Z   "isTrustingAllCertificates": false
2023-06-19T08:42:12.189282992Z }

So in order to make it work I would have to add the destinationConfiguration object which is a carbon copy of the BTP destination definition and make it part of the destination object.

I do not see it as a documented option in here: https://sap.github.io/cloud-sdk/docs/js/features/connectivity/destinations#register-destination

So the question is: is there an official way to create a destination object with a destinationConfiguration object ? Will the registration succeed and populate this into the cloud-sdk cache ?

marikaner commented 1 year ago

If your destination resides in a service binding, you should be able to retrieve your destination from the service binding using the destination fetch options (=> docs).

You can use this feature with the general getDestination(), execute() and executeHttpRequest() functions OOB. However this will go through the lookup flow as described here. You can also use the destinationForServiceBinding() function to go against the service binding directly.

This was a similar issue.

marikaner commented 1 year ago

Hey @ptesny, I'll go ahead and close this, but in case the above solution does not help, please let me know.