Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
munishsuri
Participant
8,902
Use Case - Need to propagate technical user to the on premise S4 system using methodology of principal propagation. Authenticated applications running on BTP Cloud Foundry, can now propagate technical user utilizing SAP-Connectivity-Technical-Authentication header.

We recently had a requirement where we would need to propagate the Technical user but did not want to use Basic Auth as a security.

As of Cloud Connector version 2.15, consumers of the Connectivity service can propagate technical users from the cloud application towards the on-premise systems. To achieve this a JWT token is used representing the technical user, via the SAP-Connectivity-Technical-Authentication header.This is similar to principal propagation, but in this case, a technical user is propagated instead of a business user.

In the following blog, I would try to outline an approach for achieve the same, though it is something we have used to achieve the results and may not be production ready (Of Course), because the code should be more refined while achieving the same 🙂

 

 


 

To verify and demonstrate the functionality, where an OData service is used on premise that I fetching the current user in the call and returning to the caller. From Cloud Foundry perspective there is an application that will be serving as an entry point for the User and the call is forwarded to another middleware, where the headers will be transformed for the request.

Pre Req - Principal propagation is already setup.

Let's start with the configuration on the on premise side.

  1. Create an odata service - in this specific case to test the connection, a sample odata service is created, that is going to read the logged in user and return to the caller. Attaching a sample implementation - utilizing the current DDIC structures for the same and using sy-uname.

  2.   Creation of a User in Su01

  3.  In the above step the most important part is the alias -  this is the technical user for your         communication and you can find it from the BTP Service Key, in the above case this is the service key client id of the connectivity service of the sub account where you have connected your cloud connector. We are getting via binding the middleware application with connectivity service and using the environment variables to read the data.

  4. Now you would need to map the user via transaction certrule, as the technical user is in managed in alias, we would mapping the user via alias, and the cloud connector will have Principal Propagation as a means of authentication.            



 

From the On premise perspective, we would be required to do only few additional configurations apart from the standard principal propagation setup.

 

Pre Req - Cloud Foundry Application that has XSUAA authentication and capable to call a destination.

In our POC, we have an app router, which is going to call the destination (middleware application).

XS-app.json of the app is configured in the following way,
{
"welcomeFile": "/index.html",
"authenticationMethod": "route",
"logout": {
"logoutEndpoint": "/do/logout"
},
"routes": [
{

"csrfProtection": false,
"source": "^/sap/opu/odata/sap/Z_MUNISH_SSO_SRV/(.*)$",
"target": "$1",
"destination": "middleware_sso"
},
{
"source": "^(.*)$",
"target": "$1",
"service": "html5-apps-repo-rt",
"authenticationType": "xsuaa"
}
]
}

it is pointing to middleware_sso, which is nothing but a destination created on BTP sub account for the middle ware processing, though this can be achieved by middleware chaining concept, but I am putting the middleware logic out for this POC.

Config of middleware_sso destination are shown below.


 

Till Now, we have configured the Principal Propagation and have an application available that is bounded to XSUAA and able to call the destination.

Coming to the Main part of now calling the Odata Service Destination, for that purpose we have a node js middle ware to append header and call the destination of the backend.

Start.js 
const express = require("express");
const app = express();

const SapCfAxios = require("sap-cf-axios").default;

const passport = require("passport");
const { JWTStrategy } = require("@sap/xssec");
const xsenv = require("@sap/xsenv");
const xml = require("xml");

passport.use(new JWTStrategy(xsenv.getServices({ uaa: { tag: "xsuaa" } }).uaa));
app.use(passport.initialize());
app.use(passport.authenticate("JWT", { session: false }));
var axiosSimple = require('axios');

const oVCAP_SERVICES = JSON.parse(process.env.VCAP_SERVICES);
const oConnectivityServiceCredentials =
oVCAP_SERVICES.connectivity[0].credentials;

const handleRequest = async (req, res) => {

const axios = SapCfAxios("Dest_s4_he4_sso");
var authorization = req.headers.authorization;

var params = new URLSearchParams();
params.append("client_id", oConnectivityServiceCredentials.clientid);
params.append("client_secret", oConnectivityServiceCredentials.clientsecret);
params.append("grant_type", "client_credentials");

var tokentechnical = ""
try{
var response1 = await axiosSimple({
method: "post",
url: oConnectivityServiceCredentials.token_service_url + "/oauth/token",
params: params,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json",
},
});

tokentechnical = response1.data.access_token
}catch(e){
console.log(e)
}

try{

console.log("auth",authorization)
const response = await axios({
method: "GET",
url: "/ZMUNISH001Set",
headers: {
"content-type": "application/json",
"SAP-Connectivity-Technical-Authentication":"Bearer "+tokentechnical
},

});
console.log(response.data);
res.set('Content-Type','application/json')
res.send(JSON.stringify(response.data));

}catch(e){
console.log(JSON.stringify(e))
res.send(JSON.stringify(e))
}

};

app.get("/", handleRequest);
const port = process.env.PORT || 3000;
app.listen(port, function () {
console.log("myapp listening on port " + port);
});

 

For deployment you would be needing a manifest file.
---
applications:
- name: myapp
routes:
- route: <your_host>.cfapps.eu10.hana.ondemand.com
path: myapp
memory: 128M
buildpack: nodejs_buildpack
services:
- name: conn_principalpropagation
- name: dest_principalpropagation
- name: principalpropagation-xsuaa-service

Github ref

 

In the above code we are utilizing destination Dest_s4_he4_sso, this has be created in your BTP destinations pointing to the On Premise Virtual Host.


 

Now it is time to test the flow, you can call the app router Url and it should point to the middleware, from where you should be able to connect to the on premise system via a technical user and if everything is fine, technical user should be returned in the response if configured properly.

In the current setup of min, you may view VBAK table attributes and technical user , I just utilized a standard table component, please don't get confused here.


Conclusion - setup of technical user propagation was done via a middleware application and aligning backend system to accept the certs as per the alias defined in the technical user configurations.

 
9 Comments