Role Based access in CAP
In this example, we will define roles and restrict access to specific services based on those roles.
We will be following below steps-
- Define roles in xs-security.json
- Protect your services with CDS annotations
- Check roles manually in Custom handlers (optional)
Step 1 - Define roles in xs-security.json
We wants to create 2 roles CAP-App-Admin and CAP-App-Viewer, so we can define the same in xs-security.json file like-
xs-security.json
{
"scopes": [
{
"name": "$XSAPPNAME.Admin",
"description": "Admin access"
},
{
"name": "$XSAPPNAME.Viewer",
"description": "Viewer access"
}
],
"attributes": [],
"role-templates": [
{
"name": "CAP-App-Admin",
"description": "CAP-App Admin role",
"scope-references": [
"$XSAPPNAME.Admin"
]
},
{
"name": "CAP-App-Viewer",
"description": "CAP-App Viewer role",
"scope-references": [
"$XSAPPNAME.Viewer"
]
}
]
}Step 2 - Protect your services with CDS annotations
Now since we have defined the Roles, we can now restrict the services based on the roles using @restrict in service cds file like-
srv/custom-service.cds
service CustomService @(path: 'custom-service') {
// @restrict: [{ grant: 'READ', to: ['Viewer'] },{ grant: '*', to: ['Admin'] }]
@restrict: [{ grant: '*', to: ['CAP-App-Admin'] }]
function getCustomData() returns String;
}Step 3 - Check roles manually in Custom handlers (optional)
When you need custom checks (for example, dynamic rules or complex logic), skip annotations and check in your handler code in service js file like-
srv/custom-service.js
import cds from "@sap/cds";
const CustomService = async (srv) => {
srv.on('getCustomData', async (request) => {
try {
// Custom authorization check if you don't want to use the @restrict annotation on cds file.
if (!req.user.is('CAP-App-Admin')) {
return req.reject(403, 'Not authorized');
}
const traceId = "Application is working fine" + request.id;
return {
status: 200,
data: { message: traceId }
}
}
catch (error) {
console.error('Error retrieving destination:', error);
return request.error({ code: 500, message: error.message });
}
});
}
export default CustomService;!!! Its Done !!!