ABAP Blog Posts
cancel
Showing results for 
Search instead for 
Did you mean: 
NooruBohra
Active Participant
683

In high-security environments, standard PFCG roles often aren't granular enough. Today, we’ll look at a sophisticated way to implement Row-Level Security using User-Defined Aspects. We'll walk through a real-world scenario: restricting Purchase Requisition items so users only see data for their authorized cost centers.

Now there's no such authorization object exists in SAP.

Step 1: Create the Authorization Source

First, we need a "Truth Table" that maps users to cost centers. We'll wrap our custom table (zp2p_cc_user) in a CDS view.
Note: To use a view in an Aspect, you must declare it as audited using the @AccessControl.auditing annotations.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Cost Center and Authorized Users'
@Metadata.ignorePropagatedAnnotations: true

@AccessControl.auditing.type: #CUSTOM
@AccessControl.auditing.specification: 'Custom cost center authorization table audited via logging'

define view entity ZI_CostCenterUser
  as select from zp2p_cc_user
{
  key kostl as CostCenter,
  key uname as UserName
}

Step 2: Extend the Target View

Standard views like C_PurReqnItemMntr might not expose the CostCenter field by default. We use a CDS Extension to inject this field without modifying the standard SAP object.
@AbapCatalog.sqlViewAppendName: 'ZIEXTPRMNTR'
@EndUserText.label: 'Extension for Cost Center'
extend view C_PurReqnItemMntr with zi_ext_c_purreqnitemmntr

  association [0..1] to ZI_PRCostCenter as _PRCostCenter on _PRCostCenter.PurchaseRequisition = $projection.purchaserequisition

{
  _PRCostCenter.CostCenter as CostCenterAcc
}

Step 3: Define the Access Policy and Aspect

This is where the magic happens. An Access Policy is a specialized DCL object that defines a "Generic Aspect." It effectively tells the system: "Whenever I need to know a user's cost centers, run this specific query."
To create ACCESSPOLICY,  you need to create a ACCESS CONTROL in ADT and remove the generated code.
Syntax Tip: Use WITH USER ELEMENT to bind the current system user to your table's username field.
Note: Aspect name and the Access Control name should be same.
If you encounter a "Name must be identical" error, remember that in some versions of ABAP 7.5x, the Access Policy name  and the Aspect name are required to be identical if they are in the same file.
 
@EndUserText.label: 'Aspect for User Cost Center'

define accesspolicy ZV_UserCostCenter { 
    define aspect ZV_UserCostCenter as select from
        ZI_CostCenterUser with user element UserName
        { 
            CostCenter
        }
}

Step 4: The Final Access Control (DCL Role)

Finally, we apply this rule to our Purchase Requisition view. Instead of a static value, we use the ASPECT keyword to dynamically pull values from our Access Policy.
 
@MappingRole: true
define role ZI_PURCHASEREQUISITIONITEM {
    grant select on C_PurReqnItemMntr
    combination mode AND
    where ( CostCenterAcc ) = ASPECT ZV_UserCostCenter;
}

Why Use Aspects?

  • Centralized Logic: Change your authorization table or logic in one Aspect, and every role using that Aspect updates automatically.
  • Performance: The ABAP CDS engine converts this into a highly optimized database join at runtime.
  • Flexibility: It allows you to build complex, table-driven security that standard PFCG authorization objects simply can't handle.

ST05 Trace will show that the Aspect is being used while fetching the data.

NooruBohra_1-1776920319784.png

NooruBohra_0-1776920309245.png

This blog was written with the help of AI, there might be some syntax issues or grammatical errors.
3 Comments