UI5 App Roles based access

Objective -

In this example, we will create two roles (Viewer and Admin) for a SAP UI5 application and control the visibility of application content based on the roles assigned to users in SAP BTP.

Steps -

We will be following below steps -

  • Define Roles
  • Define AppRouter User API of xsuaa service
  • Define Logic to check User access

Step 1- Define Roles

We will define the required roles in the xs-security.json file of our UI5 application.

The following example can be used as a reference -

xs-security.json
{
    "xsappname" : "<my-xsapp-name>",
    "description" : "Security profile of called applicaiton",
    
    "scope" : [
        {
            "name" : "$XSAPPNAME.Viewer",
            "description" : "Viewer Access"
        },
        {
            "name" : "$XSAPPNAME.Admin",
            "description" : "Admin Access"
        }
    ],

    "attributes" : [],

    "role-templates" : [
        {
            "name" : "MyAppViewerRole",
            "description" : "Role to View myApp",
            "scope-references" : [
                "$XSAPPNAME.Viewer"
            ]
        },
        {
            "name" : "MyAppViewerAdmin",
            "description" : "Admin Role for myApp",
            "scope-references" : [
                "$XSAPPNAME.Viewer", 
                "$XSAPPNAME.Admin"
            ]
        }
    ]
}

Step 2- Define AppRouter User API of xsuaa service

We will add the User API in the xs-app.json file of the UI5 application to retrieve the details of the currently logged-in user accessing the application.

xs-app.json
{
    "source" : "^/user-api/currentUser$",
    "target" : "/currentUser",
    "service" : "sap-approuter-userapi",
    "authenticationType" : "xsuaa"
}

So the xs-app.json file will look like-

xs-app.json
{
    "welcomeFile" : "/index.html",
    "authenticationMethod" : "route",
    "routes" : [
        {
            "source" : "^/resources/(.*)$",
            "target" : "/resources/$1",
            "authenticationType" : "none",
            "destination" : "ui5"
        },
        {
            "source" : "^/test-resources/(.*)$",
            "target" : "/test-resources/$1",
            "authenticationType" : "none",
            "destination" : "ui5"
        },
        {
            "source" : "^/user-api/currentUser$",
            "target" : "/currentUser",
            "service" : "sap-approuter-userapi",
            "authenticationType" : "xsuaa"
        },
        {
            "source" : "^(.*)$",
            "target" : "$1",
            "service" : "html5-apps-repo-rt",
            "authenticationType" : "xsuaa"
        }
    ]
}

Step 3- Define Logic to check User access

We can define the logic to check the access of Logged-in User.

Component.js

_loadUserAuthorization : async function () {
    try{
        const response = await fetch("./user-api/currentUser", {
            credentials : "same-origin",
            headers : {
                Accept : "application/json"
            }
        });

        const rawResponse = await resposne.text();

        if(!response.ok){
            throw new Error("Unable to retrieve current user with status : " + response.status);
        }

        let responseData = null ;

        try{
            responseData = JSON.parse(rawResponse);
        }
        catch(parseError){
            throw new Error("Current User didnot return valid JSON " + parseError);
        }

        const scopes = Array.isArray(responseData.scopes) ? responseData.scopes : Array.isArray(responseData.user?.scopes) ? responseData.user.scopes : [];

        console.log(scopes);
    }
    catch(error){
        console.error("Authorization check failed with error " + error);
    }
}

We will get the User roles on the response scope and can store the same on the json model based on which can control the visibility of UI elements.

!!! Its Done !!!