Scenario | Out-Of-The-Box UX | Better UX | Link to article/examples |
1. No Access - The user has no authorization to the application. | Generic 401 (Unauthorized) Error | Redirected to an “Access Denied” page, with instructions/link to how to request access. | Link (this article) |
2. Role-based actions - The user can only make changes to data when they have the correct authorization. | Generic 401 Error when trying to make changes to data | Dynamic UI which only shows authorized actions (buttons, links, etc.) | Link (Coming Soon) |
3. Role-based subset of data - The user can only access a certain subset of the data based on their authorizations. | N/A, custom filtering/coding required. | Automatic data filtering using attribute-based analytic privilege (no custom UI coding) | Link (Coming Soon) |
Project/Module | Property | Value |
Multi-Target Application Project | ||
Project Name | SecureUX | |
Application ID | SecureUX | |
HANA Database Module | ||
Module Name | db | |
NodeJS Module | ||
Module Name | api | |
Enable XSJS support | true | |
SAPUI5 HTML5 Module | ||
Module Name | ui | |
Namespace | com.sap.secureux | |
View Type | XML | |
View Name | App |
{
"xsappname": "SecureUX",
"scopes": [
{
"name": "$XSAPPNAME.Display",
"description": "display"
},
{
"name": "$XSAPPNAME.Create",
"description": "create"
},
{
"name": "$XSAPPNAME.Edit",
"description": "edit"
},
{
"name": "$XSAPPNAME.Delete",
"description": "delete"
}
],
"attributes": [
{
"name": "region",
"description": "region",
"valueType": "s"
}
],
"role-templates": [
{
"name": "Viewer",
"description": "View all records",
"scope-references": [
"$XSAPPNAME.Display"
],
"attribute-references": [
"region"
]
},
{
"name": "Editor",
"description": "Edit and Delete records",
"scope-references": [
"$XSAPPNAME.Create",
"$XSAPPNAME.Edit",
"$XSAPPNAME.Delete",
"$XSAPPNAME.Display"
],
"attribute-references": [
"region"
]
}
]
}
ID: SecureUX
_schema-version: '2.1'
version: 0.0.1
modules:
- name: ui
type: html5
path: ui
requires:
- name: core_api
group: destinations
properties:
forwardAuthToken: true
url: '~{url}'
name: core_api
- name: uaa
- name: api
type: nodejs
path: api
provides:
- name: core_api
properties:
url: '${default-url}'
requires:
- name: hdi_db
- name: uaa
- name: db
- name: db
type: hdb
path: db
requires:
- name: hdi_db
resources:
- name: uaa
type: com.sap.xs.uaa
parameters:
service-name: secureux-uaa
- name: hdi_db
properties:
hdi-container-name: '${service-name}'
type: com.sap.xs.hdi-container
try {
// Initialize hana connection/context
var oConn = $.hdb.getConnection();
var oSession = $.session;
$.response.status = $.net.http.OK;
$.response.contentType = "application/json";
$.response.setBody(JSON.stringify(oSession.securityContext));
oConn.close();
} catch(ex) {
// Return error
$.response.setBody("Failed to retrieve data");
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
}
...
var options = {
anonymous : false, // remove to authenticate calls
redirectUrl : "/index.xsjs"
};
...
{
"welcomeFile": "webapp/index.html",
"authenticationMethod": "route",
"routes": [
{
"source": "^/(.*)(.xsjs)",
"destination": "core_api",
"authenticationType": "xsuaa"
},
{
"source": "^/(.*)$",
"localDir": "resources"
}
]
}
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/m/MessageBox"
], function (Controller, JSONModel, MessageBox) {
"use strict";
return Controller.extend("com.sap.secureux.ui.controller.App", {
onInit: function(){
this.getUserContext();
},
getUserContext: function(){
var oController = this;
var urlUserContext = "/userContext.xsjs";
var oModelUserContext = new JSONModel(urlUserContext);
// This code attached to the data request and parses the response. This example handles
// error scenarios (where the service is down, where the server returns 403/access denied,
// and finally it parses the scopes in the success authentication response to see if the
// user has a specific scope.
oModelUserContext
.attachRequestFailed(function(oEvent) {
var errorObject = oEvent.getParameters();
oController._parseResponse(errorObject);
})
.attachRequestCompleted(function(oEvent) {
var dataResponse = oEvent.getSource();
var errorObject = oEvent.getParameter("errorobject");
oController._parseResponse(errorObject, dataResponse);
});
// Set the resulting sessionContext to a user JSON model and bind to the view.
this.getView().setModel(oModelUserContext, "user");
},
_parseResponse: function(oError, oData){
if (oError){
// If Access Denied is returned by the server, redirect the user to the access denied
// page.
if (oError.statusCode === 403){
this.getOwnerComponent().getRouter().navTo("accessdenied");
}
else {
// If any generic error occurs, let the user know with a message.
jQuery.sap.delayedCall(1000, this, function(){
MessageBox.error("Unable to connect to server. Please check with IT helpdesk, or try again later. (" + oError.statusCode + ":" + oError.statusText + ")");
});
}
}
else{
// Verify Access - If the user has a "Display" scope then let them have basic access.
// If no "Display" scope is found then redirect them to the access denied page.
var oScopes = oData.getProperty("/scopes");
if (oScopes.filter(function(row) {
return (row.endsWith(".Display"));
}).length === 0) {
// No Access
this.getOwnerComponent().getRouter().navTo("accessdenied");
}
}
}
});
});
<mvc:View controllerName="com.sap.secureux.ui.controller.App" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
<App id="idAppControl">
<pages>
<Page title="{i18n>title}">
<content>
<List binding="{user>/userInfo}" headerText="User Context">
<DisplayListItem label="logonName" value="{user>logonName}" />
<DisplayListItem label="givenName" value="{user>givenName}" />
<DisplayListItem label="familyName" value="{user>familyName}" />
<DisplayListItem label="email" value="{user>email}" />
</List>
<List items="{user>/scopes}" headerText="Scopes">
<DisplayListItem label="scope" value="{user>}" />
</List>
<List items="{user>/userAttributes/region}" headerText="Attributes (region)">
<DisplayListItem label="region" value="{user>}" />
</List>
</content>
</Page>
</pages>
</App>
</mvc:View>
Role | Scope | Attribute |
SecureUX-Editor-NA | Editor | NA |
SecureUX-Editor-EU | Editor | EU |
SecureUX-Viewer-NA | Viewer | NA |
SecureUX-Viewer-EU | Viewer | EU |
Role Collection | Role |
SecureUX-Editor-NA | SecureUX-Editor-NA |
SecureUX-Editor-EU | SecureUX-Editor-EU |
SecureUX-Editor-Global | SecureUX-Editor-NA SecureUX-Editor-EU |
SecureUX-Viewer-NA | SecureUX-Viewer-NA |
SecureUX-Viewer-EU | SecureUX-Viewer-EU |
SecureUX-Viewer-Global | SecureUX-Viewer-NA SecureUX-Viewer-EU |
<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:semantic="sap.m.semantic" xmlns:footerbar="sap.ushell.ui.footerbar" xmlns:l="sap.ui.layout"
controllerName="com.sap.secureux.ui.controller.AccessDenied">
<MessagePage
icon="sap-icon://locked"
showHeader="true"
title="{i18n>AccessDenied.title}"
text="{i18n>AccessDenied.text}"
description="{i18n>AccessDenied.description}"/>
</mvc:View>
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller ) {
"use strict";
return Controller.extend("com.sap.secureux.ui.controller.AccessDenied", {
onInit : function () {
}
});
}
);
title=SecureUX
appTitle=ui
appDescription=App Description
AccessDenied.title=Access Denied
AccessDenied.text=You do not have access to this application.
AccessDenied.description=Please check with your manager to request access.
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"async": true,
"viewPath": "com.sap.secureux.ui.view",
"controlAggregation": "pages",
"controlId": "idAppControl"
},
"routes": [
{
"name": "RouteView1",
"pattern": "RouteView1",
"target": [
"TargetView1"
]
},
{
"pattern": "accessdenied",
"name": "accessdenied",
"target": [
"AccessDenied"
]
}
],
"targets": {
"TargetView1": {
"viewType": "XML",
"transition": "slide",
"clearAggregation": true,
"viewName": "View1"
},
"AccessDenied": {
"viewType": "XML",
"clearAggregation": true,
"viewName": "AccessDenied"
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
17 | |
11 | |
11 | |
11 | |
11 | |
8 | |
6 | |
5 | |
5 | |
5 |