SAP BTP is a business technology platform with so-called kernel or built-in-in services like connectivity, identity, application router etc and application runtimes like Cloud Foundry, Kyma (SAP managed kubernetes), ABAP (steampunk) or Other (any bespoke runtime)
Disclaimer:
|
How to troubleshoot SAP BTP OAuth2SAMLBearerAssertion destination with SuccessFactors or any other LOB application? Especially when the SFSF BizX/other LOB user’s identity is represented by an OIDC token? Let’s see how to have destination service help troubleshoot a saml assertion that is generated internally by an OAuth2SAMLBearerAssertion type of destination, especially when having the user principal encoded in one of the supported user claim attributes of a user's JWT token (i.e. OIDC identity).
|
By default, the user principal is identified by one of the following JWT (JSON web token) attributes: ● user_name ● email ● mail ● user_uuid ● sub. When using OAuth2SAMLBearerAssertion destination with SAP BTP destination service there is no way to look up the saml bearer assertion that is being passed into the token endpoint of the destination OAuth client. As security is paramount, this is by design, as neither the saml assertion nor the private key used to signed it are ever disclosed. But again our polyvalent destination service offers a way to generate the saml assertion - using SAMLAssertion destination type. Good to know:
Please note:
|
Recently, I got a question regarding the following error message [LGN0022]Person-only not supported when gace flag is off. The error occurs when trying to call into an inbound SFSF ODATA API with a bearer access token generated by the find destination API but only when using the SAP IAS business user identity (propagated into the destination service via a user's JWT token in the x-user-token header). However, if using a the same SFSF BizX business user passed directly to destination service either directly via SystemUser property or with manually created user's JWT wrapper, the generated bearer access token allows for calling into inbound SFSF ODATA APIs without error. So the question quickly turned out to be what is the saml assertion generated with dynamic user identity represented by user JWT token and what it looks like when user identity is static and represented by the SystemUser property or a JWT wrapper ? Let's see how we can answer that question. |
Please note:
|
{
"Name" : "ACME-OAuth2SAMLBearerAssertion",
"Type" : "HTTP",
"URL" : "https://api2preview.sapsf.eu:443",
"Authentication" : "OAuth2SAMLBearerAssertion",
"ProxyType" : "Internet",
"KeyStorePassword" : "<KeyStorePassword>",
"audience" : "www.successfactors.com",
"XFSystemName" : "<XFSystemName>",
"companyId" : "<companyId>",
"authnContextClassRef" : "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession",
"apiKey" : "<SFSF OAuth client apiKey>",
"clientKey" : "<SFSF OAuth client apiKey>",
"KeyStoreLocation" : "successfactors.p12",
"nameIdFormat" : "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
"x_user_token.jwks_uri" : "https://<identityzone>.authentication.<region>.hana.ondemand.com/token_keys",
"tokenServiceURL" : "https://api2preview.sapsf.eu:443/oauth/token",
"userIdSource" : "user_name"
}
{
"Name" : "ACME-SAMLAssertion",
"Type" : "HTTP",
"URL" : "https://api2preview.sapsf.eu:443/oauth/token",
"Authentication" : "SAMLAssertion",
"ProxyType" : "Internet",
"KeyStorePassword" : "<KeyStorePassword>",
"audience" : "www.successfactors.com",
"XFSystemName" : "<companyId>",
"companyId" : "<companyId>",
"authnContextClassRef" : "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession",
"apiKey" : "<SFSF OAuth client apiKey>",
"clientKey" : "<SFSF OAuth client apiKey>",
"KeyStoreLocation" : "successfactors.p12",
"nameIdFormat" : "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
"x_user_token.jwks_uri" : "https://<identityzone>.authentication.<region>.hana.ondemand.com/token_keys",
"tokenServiceURL" : "https://api2preview.sapsf.eu:443/oauth/token"
}Both definitions look very much alike the main difference being the "Authentication" and "URL" property values. In other words getting the SAMLAssertion destination for your already working OAuth2SAMLBearerAssertion destination is really this proverbial "piece of cake". However, please consider:
|
Here goes a result of a SAMLAssertion find destination REST API call. As you can can see the find destination API echoes the destination definition in the json output. At a closer inspection you will notice that the definition is slightly different from the one above with regard to the user claim. It is not using a default "user_name" type of a claim but an "email" type of a claim. The userSourceId property can be used to tell the destination service which user claim to use. It defaults to "user_name" claim of your JWT token. And in the example below I wanted to use an email address as an JWT user claim. Please note: with an email type of user claim I had to adjust the nameIdFormat property to reflect it. |
{
"owner": {
"SubaccountId": "afbac4de-xxxx-xxxx-xxxx-f1d80ccb9ad4",
"InstanceId": null
},
"destinationConfiguration": {
"Name": "ACME-mySAMLAssertion",
"Type": "HTTP",
"URL": "https://api2preview.sapsf.eu:443/oauth/token",
"Authentication": "SAMLAssertion",
"ProxyType": "Onpremise",
"KeyStorePassword": "<KeyStorePassword>",
"userSourceId": "email",
"audience": "www.successfactors.com",
"XFSystemName": "<companyId>",
"companyId": "<companyId>",
"authnContextClassRef": "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession",
"apiKey": "<SFSF apiKey>",
"clientKey": "<SFSF apiKey>",
"KeyStoreLocation": "successfactors.p12",
"nameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"x_user_token.jwks_uri": "https://<identityzone>.authentication.<region>.hana.ondemand.com/token_keys",
"tokenServiceURL": "https://api2preview.sapsf.eu:443/oauth/token"
},
"certificates": [
{
"Name": "successfactors.p12",
"Content": "MIIQSwIBAzCCEAQGCSqGSIb3DQEHAaCCD/UEgg/xMIIP7TCCCfkGCSqGSIb3DQEHAaCCCeoEggnmMIIJ4jCCCd4GCyqGSIb3WksuH9BFWNLdtLAwqDph7ph9yG083YHYilA0IDb4s4h5cWhJVwTA+MCEwCQYFKw4DAhoFAAQUamZrU984O3v0ug9vbKnwAMnb6PMEFNHdn912ouAzXgcrD0scUuNcvnHHAgMBhqA=",
"Type": "CERTIFICATE"
}
],
"authTokens": [
{
"type": "SAML2.0",
"value": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDI6QXNzZXJ0aW9uIHhtbG5zOnNhbWwyPSJ1cm466dHlwZT0ieHNkOnN0cmluZyI+Q29tcGV0ZW5jeSBNYXRyaXggVXNlcjwvc2FtbDI6QXR0cmlidXRlVmFsdWU+PC9zYW1sMjpBdHRyaWJ1dGU+PC9zYW1sMjpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PC9zYW1sMjpBc3NlcnRpb24+",
"http_header": {
"key": "Authorization",
"value": "SAML2.0 PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDI6QXNzZXJ0aW9uIHhtbG5zOnNhbWwyPSJ1cm46bdHlwZT0ieHNkOnN0cmluZyI+Q29tcGV0ZW5jeSBNYXRyaXggVXNlcjwvc2FtbDI6QXR0cmlidXRlVmFsdWU+PC9zYW1sMjpBdHRyaWJ1dGU+PC9zYW1sMjpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PC9zYW1sMjpBc3NlcnRpb24+"
}
}
]
}
<?xml version="1.0"?>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="4904a84f-cf16-4a7a-b690-903363b08262" IssueInstant="2021-07-02T07:09:18.722Z" Version="2.0">
<script/>
<saml2:Issuer>successfactors</saml2:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#4904a84f-cf16-4a7a-b690-903363b08262">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xsd"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>ZDOFMKXBjvwqu0X19iVTSxkEuw7QfVaf0WuOv7zYR4w=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue> MHD0KMyDiDUZ6owkcLaCbD8xsU8FGdhua5CKkXE1w99cYziebDcGwwIzLQjBTxoNfbQajanoy88g aYpB9BNPaNfl90fvZ6THlMSNjKoeZKaL6xVq7lC632pan5pWui4AdTMW8jvBkssGJSyKdbGbLNc= </ds:SignatureValue>
</ds:Signature>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">firstname.lastname@acme.com</saml2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData NotOnOrAfter="2021-07-02T08:09:18.722Z" Recipient="https://api2preview.sapsf.eu:443/oauth/token"/>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:Conditions NotBefore="2021-07-02T06:09:18.722Z" NotOnOrAfter="2021-07-02T08:09:18.722Z">
<saml2:AudienceRestriction>
<saml2:Audience>www.successfactors.com</saml2:Audience>
</saml2:AudienceRestriction>
<saml2:OneTimeUse/>
</saml2:Conditions>
<saml2:AuthnStatement AuthnInstant="2021-07-02T07:09:18.722Z">
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
<saml2:AttributeStatement>
<saml2:Attribute Name="client_id">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><apikKey></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="api_key">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><apiKey></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="user_uuid">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><user_uuid></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="xs.rolecollections">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><role name></saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
<saml2:AttributeStatement>
<saml2:Attribute Name="client_id">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><apikKey></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="api_key">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><apiKey></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="user_uuid">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><user_uuid></saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="xs.rolecollections">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string"><role name></saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement> "xs.user.attributes": {},
"xs.system.attributes": {
"xs.rolecollections": [
"<role>"
]
},As aforementioned, the SystemUser property is not supported by SAMLAssertion destination. Thus let's create manually a user JWT token with the email address of the business user and let's pass that JWT token in the x-user-token header of the find destination API. (You will find an example how to do it in the following blog post.) The generated saml assertion will only have the api_key and client_id attributes. (I do not include it here for the sake of brevity.) |
Bingo, It looks like the property user_uuid (from SAP IAS) is allegedly mapped into SFSF's personGuid when calling the SFSF OAuth client token endpoint. And somehow this results in this login error on SFSF ODATA API call side. And that's all we know for now. |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 96 | |
| 36 | |
| 31 | |
| 17 | |
| 12 | |
| 9 | |
| 9 | |
| 9 | |
| 8 | |
| 8 |