Skip to Content
Technical Articles
Author's profile photo Prabhjot Bhatia

My journey of building FIORI apps from BOPF to RAP – Part 2 (Authorization on standard CUD operations)

This is the next part for the blog series .If you have not checked the overview and previous part, Please refer :  My Journey of building FIORI apps from BOPF to RAP – Part 1

In this blog, we will see the use cases to enable/disable the standard CUD (Create/Update/Delete) operations.

2. Authorization on standard CUD operations


  • For any inactive instance of any entity, Modifications wouldn’t be allowed.
  • Creation of new application is only allowed to ADMIN users and rest of the users should not be allowed to create any new application.

Approach in BOPF and RAP can be summarized as follow:

Use Cases

Programming Model 

BOPF RAP
#2 Authorization on standard CUD operations
  • Use authorization in BO and implement methods in authorization class of BO CHECK_STATIC_AUTHORITY CHECK_INSTANCE_AUTHORITY

 

Authorization Master:

  • Add authorization master in Behavior definition for root entity.
  • Implement authorization methods in behavior implementation handler class.

Feature Control:

  • Add feature control in Behavior definition for CUD operations.
  • Implement Feature control methods in behavior implementation handler class.

Data Model:


For data model details, Please refer the blogpost My Journey of building FIORI apps from BOPF to RAP – Part 1

Pre-requisites:


  1. Good knowledge on CDS Modeling (Access Control in CDS), BOPF Framework.
  2. Basic knowledge in RAP Model ( Managed Implementation )
  3. Good understanding of Authorization Model in SAP (Authorization Object and Role).

We can achieve this use case to authorize standard CUD operations using Authorization Objects and profile settings as well as to use feature control in RAP. In this blog, we will understand all possible options and readers can decide the required approach. Let’s start to dig into implementation steps in BOPF and RAP.

Custom Authorization Object:


We will use a custom authorization object in both programming models. There are 2 authorization fields:

  1. Status  : X(Active),    space(Inactive)
  2. Activity : 01(Create), 02(Change), 03(Display), 06(Delete)

Approach 1 : BOPF


Create an authorization class for the relevant BO

To create an authorization exit class for the relevant BO, open the editor for the root node and choose the Authorization tab

Application%20specific%20authorization%20class%20in%20BOPF

Application specific authorization class in BOPF

Implement static checks in the CHECK_STATIC_AUTHORITY 

This method is usually called before the execution of a BOPF core service to check whether the user has authorization to execute a specific task, such as modifying data or performing an action.

Returning parameter RV_FAILED determines if user has authorization for the action.

RV_FAILED

The value (true/false) indicates whether the authorization check failed

METHOD /bobf/if_lib_auth_draft_active~check_static_authority.

" Check the creation of new instance here
    AUTHORITY-CHECK OBJECT 'ZPB_APPLICATION' FOR USER sy-uname
                                             ID 'ACTVT' FIELD is_ctx-activity
    IF sy-subrc EQ 0.
      rv_failed = abap_false.
    ELSE.
      rv_failed = abap_true.
    ENDIF.

    " Message handling if authorization check failed
    IF rv_failed = abap_true AND is_ctx-activity EQ /bobf/cl_frw_authority_check=>sc_activity-create.
      CALL METHOD /scmtms/cl_common_helper=>msg_helper_add_symsg(
        CHANGING
          co_message = eo_message ).

      eo_message->add_message(
  is_msg  = VALUE #( msgid = 'S7'
                     msgno = 000
                     msgv1 = | No authorization to create a record |
                     msgty = /bobf/cm_frw=>co_severity_error
                 )
  iv_node = is_ctx-node_key
  iv_key  = is_ctx-bo_key
  iv_attribute = zif_i_pb_application_c=>sc_node_attribute-zi_pb_application-node_data
 ).
    ENDIF.
  ENDMETHOD.

Implement instance-based checks in the CHECK_INSTANCE_AUTHORITY

Note

This method is usually called once the static authorization check has been passed.

METHOD /bobf/if_lib_auth_draft_active~check_instance_authority.
    DATA: lt_context_data   TYPE ztipb_application,
          ls_message_textid TYPE scx_t100key.             " T100 key with parameters 

" Retrieve the data of the requested node instance
    io_read->retrieve(
        exporting
            iv_node         = is_ctx-node_key
            it_key          = it_key
        importing
            et_data         = lt_context_data
            et_failed_key   = et_failed_key
    ).

  LOOP AT lt_context_data ASSIGNING FIELD-SYMBOLS(<ls_context>).
   DATA(lv_denied) = abap_true.  " Deny access by default
" Check Update/Delete of selected instance here
     AUTHORITY-CHECK OBJECT 'ZPB_APPLICATION' 
     ID 'ACTVT' FIELD is_ctx-activity
     ID 'ZPB_STATUS' FIELD <ls_context>-isActive. 
     IF sy-subrc EQ 0.
       lv_denied = abap_false.
     ENDIF.
" Message handling if authorization check failed
    IF lv_denied = abap_true.
     INSERT VALUE #( key = <ls_context>-key ) INTO TABLE et_failed_key.
    ENDIF.
  ENDLOOP.
ENDMETHOD.

 

Approach 2 : RAP


In RAP BOs, standard operations can be checked against any unauthorized access during runtime. There are 2 ways by which we can provide authorizations on standard operations:

  1. Authorization defined on Behavior definition with Authorization master
  2. Feature control on standard operations (Create/Update/Delete)

1. Authorization on Entity


Global Authorization : used for all authorization checks depending on user

Instance Authorization : in addition to user role, It’s used for selected instance of the entity.

Note: CREATE operation and static scope actions are not valid for Instance authorization

Behavior Definition:

Go to behavior definition and set the authorization master as global and instance both on root entity.

define behavior for ZI_PB_ACTIVE_APPL alias Application
implementation in class zcl_i_pb_active_appl unique
persistent table zpb_active_appl
lock master
authorization master ( global, instance )
etag master LocalLastChangedAt
{
  create ;
  update ;
  delete ;
  association _Company { create; }

 }

 

Go to behavior definition for associated entity and set the authorization as dependent on root.

define behavior for ZI_PB_ACTIVE_COMP alias Company
implementation in class zcl_i_pb_active_comp unique
persistent table zpb_active_comp
lock dependent by _Application
authorization dependent by _Application
etag master LocalLastChangedAt
{
  update ;
  delete ;
}

 

Behavior Implementation:

As soon as we will activate the above behavior definition, we will see 2 methods created in behavior implementation for GLOBAL and INSTANCE authorizations respectively.

Global Authorization:

Go to method GET_GLOBAL_AUTHORIZATIONS and check if user is authorized for CUD operations.

METHOD get_global_authorizations.
" Check the creation of new instance here
    AUTHORITY-CHECK OBJECT 'ZPB_APPLICATION' FOR USER sy-uname
                                             ID 'ACTVT' FIELD '01'.
    IF sy-subrc = 0.
     DATA(lv_authorized) = abap_true.
    ENDIF.

    result = VALUE #( %create = COND #( WHEN lv_authorized IS INITIAL THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled ) ).

    CHECK lv_authorized IS INITIAL.
    APPEND VALUE #( %state_area       = 'AUTH_CREATE'
                    %msg              = NEW zcx_pb_application( iv_severity   = if_abap_behv_message=>severity-error
                                                                is_textid     = zcx_pb_application=>tys_create_not_allowed
                                                                iv_userid     = CONV #( cl_abap_context_info=>get_user_technical_name(  ) )
                                                                iv_context    = 'Application' )
                   ) TO reported-application.


ENDMETHOD.

Instance Authorization:

Go to method GET_INSTANCE_AUTHORIZATIONS and check if user is authorized to delete/update and create the associated entity instances for Inactive status of selected instance.

METHOD get_instance_authorizations.

** Read the status of current application record
    READ ENTITIES OF zi_pb_active_appl IN LOCAL MODE
    ENTITY Application
    FIELDS ( IsActive ) WITH CORRESPONDING #( keys )
    RESULT DATA(lt_context_data)
    FAILED failed.

    result = VALUE #( FOR ls_data IN lt_context_data
                        LET lv_authorization   = COND #( WHEN _IsAuthorized( ls_data-IsActive ) IS INITIAL THEN if_abap_behv=>auth-unauthorized ELSE if_abap_behv=>auth-allowed  )
                        IN ( %tky                         = ls_data-%tky
                             %assoc-_Company              = lv_authorization
                             %delete                      = lv_authorization
                             %update                      = lv_authorization )
                     ).
ENDMETHOD.

METHOD _IsAuthorized.
" Check Create of selected instance here
     AUTHORITY-CHECK OBJECT 'ZPB_APPLICATION' 
     ID 'ACTVT' FIELD '01'
     ID 'ZPB_STATUS' FIELD iv_status. 
     IF sy-subrc EQ 0.
       rv_authorized = abap_true.
     ENDIF.
ENDMETHOD.

 

2. Feature Control on Standard Operations


In the previous blog My Journey of building FIORI apps from BOPF to RAP – Part 1

We’ve seen that feature control can be used on custom actions to define the visibility. Similarly, we can also use feature control on CUD operations by selecting the scope( Global/Instance ).

Note: Its just another way to control the behavior of standard operations. If you are going with authorization control on entity, please try to avoid this. 

Behavior Definition:

Go to behavior definition and set the feature control on CREATE as global and DELETE/UPDATE as instance on root entity.

define behavior for ZI_PB_ACTIVE_APPL alias Application
implementation in class zcl_i_pb_active_appl unique
persistent table zpb_active_appl
lock master
authorization master ( instance )
etag master LocalLastChangedAt
{
  create ( features : global );
  update ( features : instance );
  delete ( features : instance );
  association _Company { create ( features : instance ); }
}

Go to behavior definition for associated entity and set the feature control on  DELETE/UPDATE as instance.

define behavior for ZI_PB_ACTIVE_COMP alias Company
implementation in class zcl_i_pb_active_comp unique
persistent table zpb_active_comp
lock dependent by _Application
authorization dependent by _Application
etag master LocalLastChangedAt
{
  update ( features : instance );
  delete ( features : instance );
  association _Language { create ( features : instance ); }
  association _Application { }
}

Behavior Implementation:

As soon as we will activate the above behavior definition, we will see 2 methods created in behavior implementation for GLOBAL and INSTANCE feature controls respectively.

Global Feature Control:

Go to method GET_GLOBAL_FEATURES and check if user is authorized for CUD operations.

METHOD get_global_features.
" Check the creation of new instance here
    AUTHORITY-CHECK OBJECT 'ZPB_APPLICATION' FOR USER sy-uname
                                             ID 'ACTVT' FIELD '01'.
    IF sy-subrc = 0.
     DATA(lv_authorized) = abap_true.
    ENDIF.

    result = VALUE #( %create = COND #( WHEN lv_authorized IS INITIAL THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled ) ).
    APPEND VALUE #( %state_area       = 'AUTH_CREATE'
                    %msg              = NEW zcx_pb_application( iv_severity   = if_abap_behv_message=>severity-error
                                                                is_textid     = zcx_pb_application=>tys_create_not_allowed
                                                                iv_userid     = CONV #( cl_abap_context_info=>get_user_technical_name(  ) )
                                                                iv_context    = 'Application' )
                   ) TO reported-application.

  ENDMETHOD.

Instance Feature Control:

Go to method GET_INSTANCE_FEATURES and check if user is authorized to delete/update and create the associated entity instances for Inactive status of selected instance.

  METHOD get_instance_features.
** Read the status of current application record
    READ ENTITIES OF zi_pb_active_appl IN LOCAL MODE
    ENTITY Application
    FIELDS ( IsActive ) WITH CORRESPONDING #( keys )
    RESULT DATA(lt_context_data)
    FAILED failed.

    result = VALUE #( FOR ls_data IN lt_context_data
                        LET lv_active   = COND #( WHEN _IsAuthorized( ls_data-IsActive ) IS INITIAL THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled  )
                        IN ( %tky                         = ls_data-%tky
                             %assoc-_Company              = lv_active   
                             %delete                      = lv_active   
                             %update                      = lv_active    )
                     ).

  ENDMETHOD.

  METHOD _IsAuthorized.
" Check Create of selected instance here
     AUTHORITY-CHECK OBJECT 'ZPB_APPLICATION' 
     ID 'ACTVT' FIELD '01'
     ID 'ZPB_STATUS' FIELD iv_status. 
     IF sy-subrc EQ 0.
       rv_authorized = abap_true.
     ENDIF.
  ENDMETHOD.

App Preview:


For an Inactive application ( APPL2 ), Edit and Delete operations for that instance are not allowed. On List Page, Delete button will be disabled and on Object page, Edit and Delete buttons will not be available. Also, Create button for child entity ( Company ) will not be available.

FIORI%20app%20behavior%20for%20Inactive%20Application

FIORI app behavior for Inactive Application

 

However, for an active application ( APPL1 ), Delete operation is available on List page and object page and Edit is also available on Object page. Also, Create for child entity is also available.

FIORI%20app%20preview%20for%20Active%20application

FIORI app preview for Active application

 

Conclusion:


In this blog, various options to control the unauthorized access on standard CUD operations have been discussed via BOPF and RAP models. We can also restrict the unauthorized data to be displayed on FIORI app using DCL (Data Control Language) CDS views.

In next blog in this series, we will cover the use cases to display a popup dialog using BOPF and RAP ( of course without any UI5 development ). SO stay tuned and share your feedback in comment section regarding authorization concept.

 

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Syambabu Allu
      Syambabu Allu

      Hi Prabhjot,

      Great blog.nice explanation with step by step.

      Looking for more blogs on RAP.

      Thank you,

      Syam

      Author's profile photo Prabhjot Bhatia
      Prabhjot Bhatia
      Blog Post Author

      Thanks and stay tuned for more practical scenarios in upcoming weeks. You can get an overview of the topics in first part My journey of building FIORI apps from BOPF to RAP – Part 1

      Author's profile photo Enric Castella Gonzalez
      Enric Castella Gonzalez

      Thank you very much for the post, a good way to start the change to RAP 🙂

      Author's profile photo Pavan Golesar
      Pavan Golesar

      Thanks, Good blog series, Shall try soon.

      Best Regards,

      Pavan Golesar