When was the last time you’ve read the documentation for the AUTHORITY-CHECK statement? In case you haven’t done it in a while as I did, you’ve probably missed the hint at class CL_AUTH_OBJECTS_TO_SQL which is available since ABAP 7.50.

Checking the authorization for a single value is easy. For example, if we only need to check if the user is authorized for a certain Sales Organization we can check with an authorization check via object V_VBAK_VKO:

AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
         ID 'VKORG' FIELD 'A001'
         ID 'VTWEG' DUMMY
         ID 'SPART' DUMMY
         ID 'ACTVT' FIELD '03'.

If there are multiple Sales Organizations to check there are usually two options:

  1. Select all available Sales Organizations in the SAP system. Then LOOP over the result set, do the authorization check and build a range table that contains all allowed Sales Organizations. This range will then be added in the WHERE condition of your SQL statement.

  2. Select the data first. Then LOOP over the database result, do the need authorization checks, and remove the data which the user has no authorization for from the result set.

The second option has the obvious disadvantage that eventually more data gets selected from the database than required. Even though in-memory database systems like SAP HANA are fast this should be avoided.

Class CL_AUTH_OBJECTS_TO_SQL gives some handy methods to achieve the first option with less coding.

Generate WHERE condition

First, we need to call the method CREATE_FOR_OPEN_SQL to get a new instance of CL_AUTH_OBJECTS_TO_SQL. Afterward, add the authorization objects to be checked via method ADD_AUTHORIZATION_OBJECT as shown in the below code example.

DATA(authsql) = cl_auth_objects_to_sql=>create_for_open_sql( ).

authsql->add_authorization_object(
  EXPORTING
    iv_authorization_object = 'V_VBAK_VKO'
    it_activities = VALUE #( ( auth_field = 'ACTVT' value = '03' ) )
    it_field_mapping = VALUE #(
      ( auth_field = 'VKORG'
        view_field = VALUE #( table_ddic_name = 'VBAK' field_name = 'VKORG' ) ) ) )
    it_filter = VALUE #( FOR selopt IN s_vkorg[]
      ( auth_field = 'VKORG' low = selopt-low high = selopt-high ) ) 
).   

TRY .
    DATA(where) = authsql->get_sql_condition( ).
  CATCH cx_auth_not_authorized.
    " Not authorized at all
ENDTRY.

The methods need to be called as follows.

  • IV_AUTHORIZATION_OBJECT Name of the authorization object to check
  • IT_ACTIVITIES Authorization fields and activities to be checked
  • IT_FIELD_MAPPING Field mapping to DDIC fields
  • IT_FILTER (optional) Filter to limit the values to be checked. For example, this could be based on a select-option from the selection screen to only check Sales Organizations the user wanted to select data from.

If the current user has no authorization for the specified object exception CX_AUTH_NOT_AUTHORIZED is thrown. The result of the method call is empty in case there is no restriction.

Let’s assume the current user is authorized to view the Sales Organizations S000 and S001. In this case, variable where would look like this:

( VKORG = 'S000' OR VKORG = 'S001' )

Dynamic WHERE in SQL statement

The method result can be used in a SQL statement like this:

SELECT ... FROM vbak INTO TABLE @DATA(vbak) WHERE (where).