Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
patrick_winkler
Product and Topic Expert
Product and Topic Expert
2,461

Introduction

If you use the ADT wizard to generate a business configuration maintenance object, the authorization control is based on authorization object S_TABU_NAM and the CDS view entity name of the base table.

This blog shows you how to implement additional authorization objects.

This blog is relevant for:

Further reading:

Use case 1: no CDS elements of the CDS entity are relevant for the access condition

You want to use additional authorization objects that are independent of the CDS elements of the CDS entity. This means that the configuration user can either read/edit all entities or none. This setup is recommended as the configuration user should not only work with a subset of configuration entries.

Proceed as follows:

1. Enhance the generated access control for the table entity. In this example, the authorization object ZAO_PROFILE is added.

 

@MappingRole: true
define role ZI_Example {
  grant select on ZI_Example
  where ( ) = ASPECT pfcg_auth ( 'S_TABU_NAM', ACTVT = '03', TABLE = 'ZI_EXAMPLE' )
  AND ( ) = ASPECT pfcg_auth ( 'ZAO_PROFILE', ACTVT = '03', PROFILE = 'CONFIGURATION' ) ;
}

 

2. In the generated behavior implementation class, enhance all authorization checks:

 

  METHOD get_global_authorizations.
    DATA(is_authorized) = if_abap_behv=>auth-unauthorized.
    AUTHORITY-CHECK OBJECT 'S_TABU_NAM' ID 'TABLE' FIELD 'ZI_EXAMPLE' ID 'ACTVT' FIELD '02'.
    IF sy-subrc = 0.
      AUTHORITY-CHECK OBJECT 'ZAO_PROFILE' ID 'PROFILE' FIELD 'CONFIGURATION' ID 'ACTVT' FIELD '02'.
      IF sy-subrc = 0.
        is_authorized = if_abap_behv=>auth-allowed.
      ENDIF.
    ENDIF.
    result-%update      = is_authorized.
    result-%action-Edit = is_authorized.
    result-%action-SelectCustomizingTransptReq = is_authorized.
  ENDMETHOD.

 

Use case 2: CDS elements of the CDS entity are relevant for the access condition

You want to use additional authorization objects that refer to the CDS elements of the CDS entity. This means that the configuration user may only be able to work with a subset of the configuration entries.

Example objects

The example table for plants contains the field REGION (EMEA, NA, ...) to be used for authorization control.
The configuration expert shall only work with plants from a specific region.

 

@EndUserText.label : 'Plant'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #C
@AbapCatalog.dataMaintenance : #ALLOWED
define table zplant {
  key client            : abap.clnt not null;
  key plant_id          : abap.numc(3) not null;
  region                : zd_region;
  last_changed_at       : abp_lastchange_tstmpl;
  local_last_changed_at : abp_locinst_lastchange_tstmpl;
}

 

For this purpose, an authorization object ZAO_REGION with the authorization field ZAF_REGION is created based on the data element ZD_REGION.

Adjust Authorization Control Object

Add the authorization object ZAO_REGION to the generated access control object of the table entity. This access control restricts read access to the data returned by the CDS view. For example, what you can see when you open the Custom Business Configurations app in read-only mode.

 

@MappingRole: true
define role ZI_Plant {
  grant select on ZI_Plant
  where ( ) = ASPECT pfcg_auth ( 'S_TABU_NAM', ACTVT = '03', TABLE = 'ZI_PLANT' )
  and ( Region ) = ASPECT pfcg_auth ( 'ZAO_REGION', ACTVT = '03', ZAF_REGION ) ;
}

 

Create Draft Query view

When you switch to edit mode, a draft version is created for all entities. Since the access control for the CDS view is not applied to the draft table, the user can see the draft version for entities that they would not see in display mode. To restrict read access for the draft entity, a draft query view is required.

1. Right-click the draft entity table and choose New Data Definition.
2. Enter ZR_PLANT as Name and Draft Query View: Plant as Description.
3. Select defineViewEntity as a template.
4. Set authorizationCheck to CHECK.

 

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Draft Query View: Plant'
define view entity ZR_PLANT
  as select from zplant_d
{
  key plantid                       as Plantid,
      region                        as Region,
      lastchangedat                 as Lastchangedat,
      locallastchangedat            as Locallastchangedat,
      singletonid                   as Singletonid,
      draftentitycreationdatetime   as Draftentitycreationdatetime,
      draftentitylastchangedatetime as Draftentitylastchangedatetime,
      draftadministrativedatauuid   as Draftadministrativedatauuid,
      draftentityoperationcode      as Draftentityoperationcode,
      hasactiveentity               as Hasactiveentity,
      draftfieldchanges             as Draftfieldchanges
}

 

Create an Authorization Control Object for the Draft Query View:

 

@EndUserText.label: 'Mapping Role for ZR_Plant'
@MappingRole: true
define role ZR_PLANT {
  grant 
    select
      on
        ZR_PLANT
          where inheriting conditions from entity ZI_Plant; 
}

 

In the behavior definition add the query annotation to the draft table:

draft table zplant_d query ZR_PLANT

Implement Prechecks for Operations

It must be prevented that the configuration user can create/update/delete plants for regions for which they are not authorized. This can be achieved with a pre-check of the operation.

In the behavior definition, add the annotation precheck to the action create in the singleton entity and the action update, delete in the table entity:

 

association _Plant { create ( features : instance, precheck ); with draft; }

update( features : global, precheck );
delete( features : global, precheck );

 

Place the cursor on the actions and use the quick assist (CTRL+1) to create the missing method implementations:

 

  METHOD precheck_cba_Plant.
    LOOP AT entities ASSIGNING FIELD-SYMBOL(<entity>).
      LOOP AT <entity>-%target ASSIGNING FIELD-SYMBOL(<plant>).
        AUTHORITY-CHECK OBJECT 'ZAO_REGION' ID 'ZAF_REGION' FIELD <plant>-Region ID 'ACTVT' FIELD '01'.
        CHECK sy-subrc <> 0.
        APPEND VALUE #( %cid = <plant>-%cid
                        ) TO failed-plant.
        APPEND VALUE #( %cid = <plant>-%cid
                        %element-Region = if_abap_behv=>mk-on
                        %msg = new_message_with_text( text = |Not authorized to create plants in region { <plant>-region }| ) ) TO reported-plant.
      ENDLOOP.
    ENDLOOP.
  ENDMETHOD.
  METHOD precheck_update.
    LOOP AT entities ASSIGNING FIELD-SYMBOL(<plant>).
      AUTHORITY-CHECK OBJECT 'ZAO_REGION' ID 'ZAF_REGION' FIELD <plant>-Region ID 'ACTVT' FIELD '02'.
      CHECK sy-subrc <> 0.
      APPEND VALUE #( %cid = <plant>-%cid_ref ) TO failed-plant.
      APPEND VALUE #( %cid = <plant>-%cid_ref
                      %element-Region = if_abap_behv=>mk-on
                      %msg = new_message_with_text( text = |Not authorized to change plants in region { <plant>-region }| ) ) TO reported-plant.
    ENDLOOP.
  ENDMETHOD.

  METHOD precheck_delete.
    READ ENTITY IN LOCAL MODE zi_plant
    FIELDS ( region ) WITH CORRESPONDING #( keys )
    RESULT DATA(plants).
    LOOP AT plants ASSIGNING FIELD-SYMBOL(<plant>).
      AUTHORITY-CHECK OBJECT 'ZAO_REGION' ID 'ZAF_REGION' FIELD <plant>-Region ID 'ACTVT' FIELD '06'.
      CHECK sy-subrc <> 0.
      READ TABLE keys WITH KEY draft COMPONENTS %tky = <plant>-%tky ASSIGNING FIELD-SYMBOL(<key>).
      APPEND VALUE #( %cid = <key>-%cid_ref ) TO failed-plant.
      APPEND VALUE #( %cid = <key>-%cid_ref
                      %element-Region = if_abap_behv=>mk-on
                      %msg = new_message_with_text( text = |Not authorized to delete plants in region { <plant>-region }| ) ) TO reported-plant.
    ENDLOOP.
  ENDMETHOD.

 

Consider using the authorization control also for value helps, for example, the user can only select the region for which he or she is authorized. Consider adapting or using operation defaulting so that, for example, the region field is set to the region for which the user is authorized when creating a new plant.

1 Comment