Skip to Content

Overview

Recently, I came across a situation where I had to consume an OData service that’s deployed in HANA 2.0 on-premise following XSA paradigm in a SAPUI5 application running in SAP Cloud Platform – Neo environment. In this blog, I’d like to take through the concepts and the various configuration steps that are involved in setting up communication channel between an application deployed in SCP to and HANA XSA on-premise. I’ll also describe in detail the security configuration to allow a user logged in SCP HTML5 application to access a protected resource in HANA XSA, for example an OData service that requires specific scope to access.
Assumption: I assume that you have setup your XSA environment with an external IdP. And that you are familiar with using Application Role Builder, Role Collection and assigning Role Collection to user from XSA Admin Cockpit.
To explain the steps in this document, let’s take a simple HANA XSA application following MTA paradigm containing db (hdi-container), js and an approuter module.
  • Let the db module define a simple table “Book”, and a calculation view on top of this table. The calculation view “BooksByCountry” has row-level authorization check to only return rows that matches the logged in user country. (Instance Based Authorization)
  • The js module (xsjs compatibility – nodejs runtime) provides an odata service exposing the calculation view as an entity. The OData service also requires that user has the scope “books.read” to access the service. (Functional Authorization)
  • The approuter module defines the routes in the xs-app.json along with the scopes required. As you know, this acts as the single entry point for the application, and also takes care of user authentication and authorization (partly, since the backend (js module) also needs to check the user has relevant scopes), and forwarding and caching of the JWT for the logged in user.

Let’s also define a xs-security.json file that would define the required scope, attributes and role template for the application described above. In your xs-app.json and in the odata definition, you can check the scope “read” for accessing the protected resource. And the attribute country will be used in the structured privilege on calculation view to filter rows based on the user accessing the calculation view.

{
	"xsappname": "secure_helloworld",
	"tenant-mode": "dedicated",

	"scopes": [{
		"name": "$XSAPPNAME.read",
		"description": "Read access to the odata service"
	}],

	"attributes": [{
		"name": "country",
		"description": "country",
		"valueType": "string"
	}],

	"role-templates": [{
		"name": "BooksViewer",
		"description": "View Books",
		"scope-references": [
			"$XSAPPNAME.read",
			"uaa.user"
		],
		"attribute-references": ["country"]
	}]
}

And there’s a simple UI5 application that’s display the data from the OData service.

Communication Channel & Security Configuration

Before going through the configuration steps, let me quickly go through the concepts of how the entire communication channel works and how the logged user in SCP is authenticated on XS UAA side to access the services taking care of both functional (scopes) and instance based authorizations (analytical privileges on calculation level providing row-level permissions)
The application user is authenticated when accessing the UI5 application in the SCP subaccount. The SCP subaccount is configured with an external IdP, that will authenticate the user. The application will access the service on the backend (XSA) via Cloud Connector and the destinations created. The steps that are involved in passing the user context from the SCP HTML5 application to the XSA services in the backend is as follows
  1. The user logs in to the HTML5 application authenticated by the external IdP.
  2. When accessing any protected service exposed from XSA on-premise, the backend service should be called with the JWT (JSON Web Token) that the backend service can use to verify that the user is authenticated and has the required authorizations
  3. The SCP destination configured of type “OAuth2SAMLBearerAssertion” using the configured Token Service URL exchanges the SAML bearer assertion for the JWT token. To explain the steps in detail
    1. The SAML attribute statement is created from the Principal attributes that’s assigned for this trust configuration (section 5). This is done in SCP Trust Configuration where we set the attributes that are to be mapped to the principal attributes from the SAML assertion
    2. The SAML assertion created is signed by the Service Provider Signing Key (in this case is the SCP Subaccount – Signing Key from Trust Configuration)
    3. HANA XSA is configured to trust the Local SP of the SCP Subaccount as an IdP by adding the SP’s metadata as an IdP in the XSA SAML Provider Configuration
    4. The destination service replaces the Signed SAML bearer assertion for JWT token with the Authorization Server (UAA). This is part of the OAuth2 Standard grant type urn:ietf:params:oauth:grant-type:saml2-bearer. For details on this refer to link. This is possible to exchange since the XSA already trusts the SP signing key as a valid IdP (from previous step)
    5. The JWT token holds the scope that has user been assigned, and the SAML attributes
    6. Since XSA is in the on-premise, all the interaction from SCP to XSA UAA and hence to the actual backend service is carried out via the Cloud Connector
  4. The JWT token fetched in the previous step is then sent in the header Authorization: Bearer <JWT_Token> to the backend service. Please note that here, we don’t invoke the App Router but then the actual service itself (js module).
  5. The backend service should check that user the required scope to the access the protected endpoint.
  6. As you already know access to DB in XSA is with single technical user. However, the application user is personified onto the technical user giving the JWT token. The user attributes are set at the global variables for the session and can be used in the instance based authorization in the database artifacts like Structured Privileges.

The steps that are explained above are taken care of implicitly by the destination configured in SCP. Since the XSUAA is running on-premise, it’s required to expose these endpoints as virtual mapping from the cloud connector. The destination service takes care of performing this complex flow, and fetching the service result to the browser client.

Configuration steps to setup the Communication Channel & Security

I have used an SAP Cloud Platform Identity Authentication Service (IAS) tenant to demonstrate the setup here. The steps should work with any other SAML2.0 IdP as well.

Overview of configuration steps

Please note, I’ll not go through all the steps below – since some of them can be looked up from the Reference Guide, and I’ve provided the links to the documentation for the same.

I’d explain in detail the steps in the following sections that are specific to the setup discussed in this blog.

  1. Configure Role and Role Collections (documentation)
  2. Establish trust between Identity Provider (IAS tenant) and the Service Provider (HANA XSA)
    1. Configure external IdP for the HANA XSA Application server (documentation)
    2. Assign Role Collections to users (federation through Groups attribute) – (documentation)
    3. Register the SP in the IdP as an application
  3. Setup the SAP Cloud Connector
    1. Expose XSUAA endpoints
    2. Expose the service endpoints of the nodejs application (js module of MTA)
  4. Setting up destinations on the SAP Cloud Platform
  5. Configure the SCP subaccount with an external IdP
  6. Configure SCP SubAccount Local Identity Provider as an additional IdP

1. Configure Role and Role Collections

Once you have created the XSUAA service, you can maintain the Roles and the Role Collection from the admin cockpit. For this simple application, I created a role BooksViewer from the role template BooksViewer, and then assigned the attribute values from SAML as shown below

Also, I’ve created a Role Collection BooksOrganizer containing the role BooksViewer

2. Configure the External IdP for XSA

2.1 Steps to configure an external IdP for XSA

I hope you have already configured an external IdP for authenticating business user to access the application in XSA. You can refer the documentation from the table above.

2.2 Assign Role Collections to users (federation through Groups attribute)

1. Open the “SAML Identity Provider Configuration” tile from the XS Advanced Administration Cockpit
2. Select the IdP that you have configured. From the Role Collections tab, add the Role Collections that you have already created “BooksOrganizer”, and then assign the “Groups” attribute value.
In our example, I’ve setup a User Group “BooksOrgUserGroup” on IAS tenant. And users belonging to this group will be federated to the Role Collection based on this configuration

3. When a user logs in via IdP, the user gets federated to the role collections which matches to the Groups SAML assertion attribute that the logged user carries in his SAML Assertion attribute statement.

2.3 Register the SP in the IdP as an application

You can register XSA as Service Provider with any SAML2.0 complaint IdP. In the table above, I’ve given the link for configuring with IAS tenant (SaaS). Once you have SAML trust setup, you can then add the Role Collection assignment to user logging in from IdP via the Groups attribute.
From your IdP, make sure that you send the assertion attribute “Groups” (which decides the role collection that user will be federated) and “country”(used for instance based auth in our example) attribute that we will be using later on.
You can try to access the odata service via AppRouter, and then you’d see the link for the IdP below the default form login. You can then login with a valid user from IdP who has the User Group “BooksOrgUserGroup” assigned so that he gets the Role Collection “BooksOrganizer” and is able to access the service.
Now that you are able to access the OData service from XSA directly via AppRouter, the next step will be to consume the same from the UI5 application deployed in SCP Neo.

3. Configurations in SAP Cloud Connector for enabling the communication channel

I assume that you have already setup SAP Cloud Connector (SCC), and you have established the tunnel for your subaccount on SCP (Neo). You can refer to other blogs, that would describe the basic setup in detail.

In here, I’ll focus on setting up the Virtual that are specific to the consume the service from XSA On-premise. We’ll need to create two Virtual endpoints for the on-premise system, one to access the odata service, and the other access the UAA token service.

3.1 Expose the XSUAA endpoints

1. Open the Cloud Connector Admin Page
2. Select the SCP subaccount to which the backend services has to be exposed.

3. Create a mapping to the virtual system with the following details as shown in the snapshot below

Property Value
Back-end Type SAP HANA
Protocol HTTPS
Virtual Host <chosen host as per preference>
Virtual Port 39032 (Can be looked from the env of your application bound with XSUAA instance)
Internal Host <HANA XSA Host> (Can be looked from the env of your application bound with XSUAA instance)
Internal Port 39032

A sample configuration is shown below.

NOTE: The internal host and the ports will change per your system landscape. I’m running here an HANA Express edition locally on my laptop
4. Create the resources that can be accessed on the internal system with the following details
Property Value
URL Path /uaa-security/
Access Policy Path and all sub-paths

3.2 Expose the service endpoints for OData Service

In this section, we’ll configure to expose the backend service endpoints.

Fetch the backend service endpoints (js module).

Please note, in this case we go to the backend Node JS service directly, and not via the AppRouter.
You can create virtual mapping and the resources as shown in the images below.

   

4. Setup the destinations on the SAP Cloud Platform

In this step, we create the destination that will be used from the HTML5 application to consume the odata service on XSA on-premise
1. From the SAP Cloud Platform subaccount, go to Connectivity → Destinations
2. We’ll be needing the OAuth Token Service endpoint to configure the destination. You can get the same from the XS Client tool, and doing
xs env <js_app_name>
Sample output
"VCAP_SERVICES" : {
    "xsuaa" : [ {
      "name" : "uaa_books",
      "label" : "xsuaa",
      "tags" : [ "xsuaa" ],
      "plan" : "default",
      "credentials" : {
        "tenantmode" : "dedicated",
        "clientid" : "sb-secure_helloworld",
        "verificationkey" : "***",
        "xsappname" : "secure_helloworld",
        "identityzone" : "uaa",
        "identityzoneid" : "uaa",
        "clientsecret" : "***",
        "url" : "https://hxehost:39032/uaa-security"
      }
    } ]
  }

2. Create the destination with the following details.

Property Mapping Attribute in Environment Sample Value
Type N/A HTTP
audience <url>/oauth/token https://hxehost:39032/uaa-security/oauth/token
Authentication NA OAuth2SAMLBearerAssertion
tokenServiceURL <url>/oauth/token https://hxehost:39032/uaa-security/oauth/token
ProxyType N/A OnPremise
URL Backend (js module) Application URL on XSA https://hxehost:51046
tokenServiceUser <clientid> sb-secure_helloworld
tokenServicePassword <clientsecret> ***
Additional Properties
Property Value
WebIDEUsage odata_gen
WebIDEEnabled true
WebIDESystem HXE

 

Sample Configuration

3. Test the connection to ensure that the system is reachable.

 

5. Configure SCP SubAccount with an external IdP

I assume that you have configured your Neo Subaccount with an external IdP. More details on this can be found here

When the user is propagated from the SCP HTML5 application to XSA, the Local Service Provider in SCP SubAccount will act as the IdP for XSA. The outbound SAML assertion will be signed by the SP’s signing certificate. For this purpose, we’ll have to download SP metadata.
  1. From the subaccount cockpit, Go to Security → Trust, and then open the Local Service Provider tab.
  2. Download the SP metadata by clicking on the “Get Metadata” link.
  3. Since the RoleCollection assignment to user is based on the Groups attribute passed, it’s important to send that as an Assertion attribute from SCP. This is achieved by setting the Assertion attribute.
    1. Go to Security → Trust → Application Identity Provider → click on the configured IdP link
    2. Go to Attributes tab, and then add the Groups attribute into the section Assertion-Based Attributes.
    3. If there are more attributes to be passed to XSA for row level access (instance based authorization), all of them has to be added to the list here. You can set all attributes passed from IdP as Principal attributes by just entering * in Assertion & Principal Attribute.

6. Configure SCP SubAccount Local Identity Provider as an additional IdP

Finally, we will now add the Local Service Provider of SCP SubAccount as an IdP to XSA.
  1. From the admin cockpit, navigate to SAML Identity Provider Configuration tile
  2. Add the metadata from got from the Local Service Provider (previous section)
  3. Save the configuration.
  4. Configure the role collections as we did while configuring an external IdP for XSA. (refer to section 2.2 – Assign Role Collections to users)

Testing the HTML5 application on SCP

I created a simple Fiori list report application (from the project template). In the step where it asks for you select the odata service, you can select from the destination that you have created.

You can go ahead and then complete the application. The goal of this application is to show that based on the user logging in, the data fetched from the odata service is filtered based on the attributes configured for him in his IdP.

For User with country attribute as “US”

Similarly, when you login with a user with country SAML attribute as “IN”, he would only get records having that value in COUNTRY column from Calculation View.
You can also check the attributes that’s set for this session as below
SELECT KEY, VALUE from M_SESSION_CONTEXT WHERE KEY LIKE 'XS_%'
Wrapping the same in xsjs service to display the attributes that are captured at the session level is  highlighted below.
Also when the user is moved out of the user group in the IdP, he’d automatically not be allowed to access the odata service, since the user will not have the required scopes. And will be presented with the following error message.

Hope you enjoyed reading through this blog. Feedbacks are most welcome 🙂
To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

Leave a Reply