Skip to Content
Author's profile photo Bhoomika Agarwal

Guide for User Authentication and Authorization in SAP Cloud Platform


User account and authentication(UAA) is the process by which an application identifies a user, verifies his/her identity and then checks if he/she has the required permissions to access the application. This process is essential in ensuring the security of an application.

In this blog post, we explain the UAA setup process for an application that has its back-end as a Java application and the front-end/UI as a UI5 application. We begin with explaining the basics of the UAA process – the terminology, the services, the protocols and the flow. Following this, we look into the installation and setup of the Application Router and the configurations required in the Identity Provider to setup the user authorization. Lastly, we explain the process of securing the back-end service through assertions and how to access the same from the front-end/UI.


Identification vs. Authentication vs. Authorization

Every application must be able to:

  • identify a user (to be able to hold user data and distinguish different users by a unique ID)
  • authenticate a user (to be able to prove the identity of a user based on a user-secret shared with the application)
  • assign authorizations to a user and enforce these (to be able to define, assign and enforce policies of system-usage)


  • Identification – Making a claim about who you are (via username, e-mail, etc.)
  • Authentication – Proving you are who you claim to be (via password, certificate, token, single sign-on, etc.) SAML 2.0 is protocol used for authentication.
  • Authorization – Authorization is the function of specifying access rights/privileges to resources. Authorization allows what you can do on the system, once you have been authenticated. OAuth 2.0 is the protocol used for authorization.

AppRouter: Instead of letting the customer access this application directly, we will use the Application Router (App Router) which serves the following purposes.

  1. App Router is a general entry point into the application for web browsers- routing requests to the required services/routes.
  2. App Router is responsible for managing authentication flows. The App Router takes incoming, unauthenticated requests from users and initiates an OAuth2 flow with the XSUAA
  3. App Router handles multi-tenancy in applications. Each multi-tenant application has to deploy its own application router, and the application router handles requests of all tenants to the application. Refer here for more details of the role of App Router in handling multi-tenancy
  4. Handle security functionality like CSRF protections and start authorization checks

The following services are used for UAA:

Authorization server: Issues access tokens for the client to obtain the authorizations of the resource owner after he was successfully authenticated by an external identity provider, e.g. a SAML 2.0 compliant identity provider. An access token represents credentials used to access protected resources.

Identity Provider:  Identity provider used for authenticating user.

The following protocols are used for UAA:

SAML 2.0: The Security Assertion Markup Language (SAML 2.0) is an open standard based on XML for exchanging authentication and authorization data of a principal (user) between an identity provider (IdP) and a service provider (SP).

See here for further details about SAML 2.0

OAuth 2.0: The OAuth  2.0 specification defines a delegation protocol that is useful for conveying authorization decisions. OAuth is used in a wide variety of applications, including providing mechanisms for user authentication.

See here for further details about OAuth 2.0


JWT Token:

JSON Web Token (JWT) (RFC 7519) is an emerging open standard that defines a compact token format for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed with the private key of the authorization server (UAA service).


Authentication sequence in XS-UAA

A combination of SAML 2.0 and OAuth 2.0 was chosen to implement authentication and authorization for XSA security.

The sequence flow of the authentication and authorization assignment process is depicted in the next diagram:

  1. The browser sends its first request to the business app and hits the approuter. The approuter considers this as the initial request, because a session id is not included.
  2. The approuter redirects the request to the XSA UAA component. The URL for the redirect is taken from the variable VCAP_SERVICES of the approuter environment.
  3. The browser sends the request to the XSA UAA component. The XSA UAA considers this as the initial request, because a JWT token is not included.
  4. The XSA UAA redirects the request to the SAML 2.0 IdP. The URL for the redirect is taken from the configuration which was maintained when the trusted relationship between XSA UAA and SAML 2.0 IdP was set up.
  5. The browser sends the request to the SAML 2.0 IdP. The SAML 2.0 IdP considers this as the initial request, because authentication was not provided.
  6. The SAML 2.0 IdP responds with a login page.
  7. The user enters his credentials and sends a request with his credentials.
  8. The SAML 2.0 IdP authenticates the user, creates a SAML 2.0 Bearer Assertion and includes it in the response. The response is redirected back to the XSA UAA.
  9. The browser sends the request with the SAML 2.0 Bearer Assertion to the XSA UAA component. XSA UAA considers this request as authenticated and uses the information of the Bearer Assertion to create a JWT Token and an “Authorization Code”. XSA UAA keeps the JWT Token and includes the Authorization Code in the response. The response is redirected to the approuter.
  10. The browser sends the request with the “Authorization Code” to the approuter. The approuter considers this request as authenticated and uses the “Authorization Code” to request the JWT Token from XSA UAA. The approuter uses his “clientid” and “clientsecret” to authenticate itself against XSA UAA.
  11. The XSA UAA component retrieves the JWT Token which was associated to the “Authorization Code” and includes it in the response.
  12. The approuter has now the JWT Token. It creates a session id and assigns it to the JWT Token. The JWT Token is added to the browser request and forwarded to the micro service.
  13. The approuter includes the session id in the response and routes the response back to the browser.
  14. Subsequent browser requests include the session id. The approuter derives the JWT Token from the session id, adds it to the subsequent request and forwards the request to the micro service.

In this flow it is important to notice that the JWT Token never appears in the browser. This is achieved by the “Authorization Code”: with it, the user “authorizes” the approuter to obtain the authorizations – the JWT Token – from the XSA UAA component. The browser never needs to know about the authorizations, because the approuter enriches each subsequent request with the JWT Token, before the request is routed to the micro service.




The App Router can be installed in two different ways: (1) Download from Service Marketplace and (2) Download from the SAP NPM Registry. These steps are explained below:

Alternative 1: Get the App Router via Service Marketplace

  1. Before you can start the setup and configuration of the App Router component you need to download the XSA Javascript package from Service Marketplace: At the time of writing the package XS_JSCRIPT14_3-70001363.ZIP is the most recent one.
  2. After downloading the package extract it to your favorite <location>
  3. cd <location>/@sap
  4. Copy the approuter directory to some newly created directory that we call <destLocation>

Alternative 2: Get the App Router via SAP NPM Registry

This alternative approach requires that you have npm installed on your machine (already installed if you using vagrant image for your vm).

  1. Go to your favourite <destLocation> and create the approuter directory
cd <destLocation>mkdir approutercd approuter

2. Place the following package.json in your approuter directory.

  "name": "approuter",
  "dependencies": {
    "@sap/approuter": "*"
  "scripts": {
    "start": "node node_modules/@sap/approuter/approuter.js"

It contains name of approuter,dependencies,start point of approuter application

3. Install AppRouter dependencies using the following commands

npm config set @sap:registry
npm install



  1. Within <destLocation>/approuter create a new file called xs-app.json with the following content
  "routes": [
  "source": "/service",
    "target": "/",
    "destination": "service-destination"
  "source": "/",
    "target": "/",
    "destination": "ui-destination"

The xs-app.json file contains routes to backend service.

/service can be used for your backing service (java service layer)
All references to your service from your UI or any other host will have to prefix /service to the controller path.

If you have multiple UI5 applications, then you can configure them with different source endpoints and “/” as the target for each.

  "routes": [
  "source": "/service/",
    "target": "/",
    "destination": "service-destination"
  "source": "/ui1/",
    "target": "/",
    "destination": "ui1-destination"
  "source": "/ui2/",
    "target": "/",
    "destination": "ui2-destination"
  1. Within <destLocation> create a new yml file for the AppRouter microservice with the following content as reference. Be sure to check the validity of your manifest file using
    buildpack: nodejs_buildpack
      SAP_JWT_TRUST_ACL: "[{\"clientid\" : \"*\", \"identityzone\" : \"*\"}]"
      destinations: "[{\"name\":\"service-destination\", \"url\" :\"\", \"forwardAuthToken\": true}, {\"name\":\"ui-destination\", \"url\" :\"\", \"forwardAuthToken\": true}]"
    host: hostname
    memory: 128M
    name: approuterName
    path: approuter
      - yourxsuaaservicename

Manifest.yml file contains information about credentials of approuter, tenant host pattern variable, destinations, hostname, memory,  path and services.

Variables/sections description used in manifest.yml file:

  • The TENANT_HOST_PATTERN is a variable that declares the pattern how multiple tenants in the URL are identified and handled.
  • SAP_JWT_TRUST_ACL represents credentials for approuter.
  • Destinations is a variable that declares the internal routes from the App Router to the underlying backend microservices.This app-destination is referenced by the previously created xs-app.json file.
  • The Services section declares to bind our own XSUAA service instance to the App Router. This binding will ensure a corresponding VCAP_SERVICE entry that holds the client ID, client secret and public key that is required to validate any incoming OAuth token/JWT from the XSUAA service.
  1. Now we need to create a service binding to the XSUAA service. As a prerequisite we require a xs-security.json(security descriptor) file that contains a declaration about authorization scopes we intend to use in our application. We put this file to <destLocation>/xs-security.json.
    "xsappname": "xsuaaDemo",
    "tenant-mode": "shared",
    "scopes": [
            "name": "$XSAPPNAME.Scope1",
            "description": ""
            "name": "$XSAPPNAME.Scope2",
            "description": ""
    "role-templates": [
            "name": "Role1",
            "description": "",
            "scope-references": [
            "name": "Role2",
            "description": "SOC Administrator Role Template",
            "scope-references": [

Note 1: The xsappname has to be unique within the entire XSUAA instance.

Note 2: the variable  tenant-mode:shared assumes a multi-tenant application and will require the TENANT_HOST_PATTERN variable to be declared. You may also use “tenant-mode”: “dedicated” if you develop a single-tenant application.
Here we have defined two scopes and two roles respective to these scopes. Our Java application endpoints can be protected using scopes only and the application role builder at the tenant end only recognizes role templates. This is the reason for creating two role collections for both scopes. Later, we will map the groups that we will shortly create in the IdP (Identity Provider) to these role collections/templates.

  1. Navigate to the location <destLocation>

We then create a service instance called yourxsuaaservicename of the XSUAA service by issuing the following command and using the xs-security.json file:

cf create-service xsuaa application yourxsuaaservicename -c xs-security.json

Note : To activate the multi-tenancy mode, the uaa instances of the applications MUST use the service plan “application”.

  1. Ensure that xs-app.json and json and the node_modules directory with content are present in <destLocation>
  2. Then deploy the AppRouter using the following (with the appropriate API endpoint of your Cloud Foundry region):
cd <destLocation>
cf api
cf login
cf push
  1. Map the approuter route to repective tenant. Using following command.
cf map-route approuterName -n tenantName-hostname


Configuration in Identity Provider and Tenant:

Admin Configurations-

  1. To create groups and users in your Identity Provider, we will need access to the Administration Console of SAP Cloud Identity (SCI). Link for how to do this :
  2. Setup the two-way trust between the tenant and your identity provider following these steps. In most cases, an existing tenant and identity provider and the configurations will be present.
  3. You need to have your application users in this identity provider in order to assign them to their respective groups. Each user can register here.

Alternatively, users can also be created using User Management.

  1. Login to the admin console and setup the required user groups.

  1. Assignment of users to groups is done using User Management. Head over to the user in user management and then assign them the group using User Groups tab.

  1. In order to get access to Application Role Builder and SAML IDP the user needs to be assigned to the admin user group.
  2. Click on Application Role Builder and go to Applications tab and search for the application name as defined in xs-security.json in the approuter in the “xsappname” . It will be appended with !t37.

  1. Check whether the Scopes and Roles are same as you defined in the xs-security.json file
  2. Click on Role Collection tab from the sidebar and create a role collection that will be ultimately mapped to the user group after being mapped to the application roles we specified in the xs-security.json which are in turn mapped to the scopes.

10. Click on the newly created role collection in the Role Collections tab. Go to the roles section. Add Application Role. Choose you xsappname!t37 and then chose the respective Application role that will be SOMAdmin in your case.

  1. Similarly create another role collection and add application role to the newly created role collection.
  2. Now go back to the admin page and chose SAML IDP ( . Here we map the Role Collection we created to the Groups from the Identity Provider (which have been assigned to the users)

13. Create another Application Role (xsuaaRole2) and map it to AppGrp2 before hitting save.


Securing your Java Backend Service

You can prevent unauthorized and/or unauthenticated users from accessing you Java service. It is not necessary to protect a UI5 application if all the data is being fetched from the java service. The UI will hit the java service through approuter itself and if your UI5 application has been configured as one of the destinations in xs-security.json then the authorization token will be forwarded to the UI5 application as well which in turn will be forwarded along with each request that the UI5 application makes to the java service.

The steps are:

  1. Add the following dependencies in your pom.xml
  1. Introduce a new class into your project

import java.util.Arrays;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;


public class WebSecurityConfig extends ResourceServerConfigurerAdapter {

    private static final String DISPLAY_SCOPE_SOM = "AppRole1";
    private static final String DISPLAY_SCOPE_SOC = "AppRole2";
    public static final String REGEX_TENANT_INDEX = "(!t\\d+)?.";
    private static final String XSAPPNAME = "your xs app name as defined in xs-security.json";
    public static final String DISPLAY_SCOPE = XSAPPNAME + "." + DISPLAY_SCOPE_SOM;
    public static final String UPDATE_SCOPE = XSAPPNAME + "." + DISPLAY_SCOPE_SOC;

    // configure Spring Security, demand authentication and specific scopes

    public void configure(HttpSecurity http) throws Exception { //

        String hasScopeSOMAdmin = "#oauth2.hasScopeMatching('" + XSAPPNAME + REGEX_TENANT_INDEX + DISPLAY_SCOPE_SOM
                + "')";

        String hasScopeSOCAdmin = "#oauth2.hasScopeMatching('" + XSAPPNAME + REGEX_TENANT_INDEX + DISPLAY_SCOPE_SOC
                + "')";
	      //to enable cors

                .antMatchers("POST", "/abc/def").access(hasScopeSOCAdmin)
                .antMatchers("PUT", "/abc/def").access(hasScopeSOCAdmin)

                .antMatchers("POST", "/efg/**").access(hasScopeSOMAdmin)
                .antMatchers("PUT", "/efg/**").access(hasScopeSOMAdmin)
                .antMatchers("GET", "/efg/**").access(hasScopeSOMAdmin)
                .antMatchers("DELETE", "/efg/**").access(hasScopeSOMAdmin)


        // http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
	  //for cors configuration
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();

        List<String> allowedMethods = Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH");

        // The value of the 'Access-Control-Allow-Origin' header in the response
        // must not be the wildcard '*' when the request's credentials mode is
        // 'include'.
        configuration.addAllowedOrigin("your approuter url");


        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    // configure offline verification which checks if any provided JWT was
    // properly signed
    //this is required
    protected SAPOfflineTokenServicesCloud offlineTokenServices() {
        return new SAPOfflineTokenServicesCloud();

3.      In your java service’s manifest file, include the xsuaa service instance name as you mentioned in the approuter.

 - yourpersistenceservice
 - yourxsuaaservicename
  1. Build and Redeploy your java app after adding this code and you should be getting 403 unauthorized when trying to access it directly. The same should work when going through approuter.


Changes Required in application UI code:

  1. If you have a UI5 application making ajax calls to your service then use the approuterurl/service/endpoint pattern as the url for your requests.
  2. GET requests will get served without the need of CSRF tokens but POST and PUT requests will require a CSRF token to be sent otherwise you will get a 403 Forbidden.
  3. To get the CSRF token you need to add a header that requests a CSRF token in any of the GET requests to your service. The response header will contain the CSRF token required. Eg:

For persistence of the token you can use this template:

var token = {			
"csrfToken" : ""

var oToken = new sap.ui.model.json.JSONModel(token);
var tokenModel=sap.ui.getCore().getModel("oToken").getData();

In any of your GET jquery ajax requests:

headers: {
		ContentType: 'application/json',
		Accept: 'application/json',
		cache: false,
		'X-CSRF-Token': 'Fetch'

Then retrieve the token from the response:

.done(function(data, textStatus, request) {
		tokenModel["csrfToken"] = request.getResponseHeader('X-Csrf-Token');

Then in any of your POST/PUT requests:

var tokenModel = sap.ui.getCore().getModel("oToken").getData();
	var token = tokenModel["csrfToken"];
	headers : {'X-CSRF-Token': token}



We would like to acknowledge the guidance, support and effort put into the research of this topic by Saksham Gupta. He pointed us in the right direction and guided us throughout the research and implementation of the topic. We could not have taken this task to completion without his untiring efforts and research.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Matheus Oliveira Goulart
      Matheus Oliveira Goulart

      Hello Bhoomika, nice blog, congrats !!

      See if you can help me, but I'm using on-premise HANA 2.0 (no cloud foundry scenario).

      I'm consuming an external application througth an UI5 app using ajax (rest service). This external service uses Bearer authorization.

      When i deployed the application as stand-alone works perfectly, but i do need to create a site / launchpad for it. When I'm calling this application inside launchap / site, the site router is tring to authenticate the backend Bearer token into HANA (but this token needs to be forwarded to backend system). It returns me the http 401 error (unauthorized - invalid bearer ).

      I've already set the xs-app.json AuthenticationMethod as none.

      I did not create a manifest.yaml file referring to the destination and the service xsuaa, could this be the problem?



      Author's profile photo Saksham Gupta
      Saksham Gupta

      Hi Matheus,


      You need to have the xsuaa service binding to all the services which are going to interact with your application. I would also recommend you add the destinations and have the forwardAuthToken parameter as true in the manifest.


      Please let me know if that works for you 🙂

      Author's profile photo bernardo ferreira
      bernardo ferreira

      Hi Saksham,


      I have a similar issue of Matheus. I have a spring boot application with ui5 frontend and I was trying to set up the authentication. I followed this guide, set up the approuter without a problem, but when I am securing the backend I get 401 - invalid bearer token.


      I have the destination set up in the approuter and the fowardAuthToken parameter in the manifest.yml.


      Could you help me figuring out what could be missing?


      Thank you in advance!

      Author's profile photo Saksham Gupta
      Saksham Gupta

      Hi Bernardo,


      Sorry for the late reply.


      I suspect you are not sending the auth token with your requests.


      Could you elaborate on the problem? Are you getting this error on a GET or POST call and whether you have set up the correct route according to your org.



      Author's profile photo Arun Suresh
      Arun Suresh

      Very informative blog!

      I have a question regarding the versions of the libraries. I am assuming that the security-commons and java-container-security library versions have been updated since this blog was written.

      Where can i check the latest stable release versions of these libraries?




      Author's profile photo Mathias Essenpreis
      Mathias Essenpreis

      Great post. However some things have changed, e.g. now administration is done fully in cloud cockpit.

      Here is a tutorial with a spring boot app, showing new UIs.

      Author's profile photo Juliano Brugnago
      Juliano Brugnago

      Bhoomika, nice blog, well done !!

      I hope you can help me out!

      You mention that multitenancy can be achieved using the approuter and the uaa, but i can't get it working.

      For the first subaccount where the application runs everything works fine.


      Redirects to authentication page and everything works fine:

      But when i try


      Redirects to authentication:

      And then after i try to login i get the message saying that the clientid doesnt exist.

      No client with requested id: sb-devcli-fluxserver!t468

      This clientid is registered in the binding of the application with uaa, but what i understand is that is only registered bcfdev identity zone.

      Is there anything that I am missing?



      Author's profile photo Treasa PA
      Treasa PA

      Hi Juliano,


      I'm also facing similar issue. Did you find a solution to this? If yes, could you please share?




      Author's profile photo Abhishek Ramesh
      Abhishek Ramesh

      How to hide XSAPPNAME in error description, security issue.

      ​If a user tries to make any request using Wrong token(Valid in one sub account but not in another subaccount or token for different microservice). Following is the response message. Example:


      "error": "invalid_token",

      "error_description": "Client Id of the access token &quot;sb-inventory-uaa-I-SUBACCOUNT-A!b512; does not match with the OAuth Client Id &quot;sb-inventory-uaa-I-SUBACCOUNT-B!b512&quot; of the application. No JWT trust ACL (SAP_JWT_TRUST_ACL) specified in environment."


      Response message says you are missing particular client id for this action.

      The error message is correct, indicating that the exception handling is fine. But the issue is xsappname is compromised and this is a security threat. Is there a way to hide the xsappname from the error description message.

      Please provide your solution.

      Author's profile photo Guilherme Cattani
      Guilherme Cattani

      Hi Bhoomika!


      After creating an approuter and routing to a UI5 app. I keep getting errors with Component.js and the namespace.

      Can you point me towards a solution or a place that I could find it? Thank you!

      Author's profile photo Josimar Campos
      Josimar Campos


      i have an ui app (ionic), and a service backend app (spring microservices), the appRouter is setted as the example, but when i am trying to access the backend service, this is not working. the backend service is the one is secure using xsuaa. it sends a 404 not found error.


      can some one help with this?


      now i get the csrf token, but when i put it into the POST headers request an error occurs:



      error_descriptionCould not verify the provided CSRF token because your session was not found.


      UPDATE 2:

      I disabled the csrf token. it works calling the service backend using the url from the service backend but it does not work using the [approuter]/service/endpoint

      mi routes from the approuter is the next one:

      "routes": [
      "source": "/",
      "target": "/",
      "destination": "ui-destination"
      "source": "/service",
      "target": "/",
      "destination": "service-destination"


      Author's profile photo Rajdeep BHUVA
      Rajdeep BHUVA



      Thank you for the sharing details on UAA service.

      I am trying to register one service on SAP ABAP system through RFC connection. This service is part of MTA application deployed on cloud foundry.

      Do you know how to get Bearer token and establish the connection in SAP ABAP system?

      I tried with HTTP connection to external server but it will redirect to UAA service and my saved credential couldn't pass to redirected URL.



      Rajdeep Bhuva

      Author's profile photo Kush Sharma
      Kush Sharma


      I want to have a route with only authentication with userId and password (no scope check from xsuaa) and another route with authentication and authorization (scope check from xsuaa). Can you help me figure out how the xsapp.json would look like?