ABAP Authorization Checks: AUTHORITY-CHECK

Category
ABAP-Statements
Published
Author
Johannes

Authorization checks are essential for the security of SAP applications. With AUTHORITY-CHECK you verify whether a user has the required authorizations for an action.

Basic Concept

TermDescription
Authorization ObjectDefines checkable fields (e.g., S_TCODE)
Authorization FieldSingle field in the object (e.g., TCD)
AuthorizationConcrete values for fields
RoleCollection of authorizations
ProfileTechnical assignment to user

Syntax

AUTHORITY-CHECK OBJECT 'OBJECT_NAME'
ID 'FIELD1' FIELD value1
ID 'FIELD2' FIELD value2
ID 'FIELD3' DUMMY.
IF sy-subrc <> 0.
" No authorization
ENDIF.

Examples

1. Simple Authorization Check

" Check if user is authorized to execute transaction
AUTHORITY-CHECK OBJECT 'S_TCODE'
ID 'TCD' FIELD 'VA01'.
IF sy-subrc <> 0.
MESSAGE e001(zmessages) WITH 'VA01'.
" 'You are not authorized for transaction VA01'
RETURN.
ENDIF.
" Execute transaction
CALL TRANSACTION 'VA01'.

2. Check Multiple Fields

" Authorization object with multiple fields
AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
ID 'VKORG' FIELD '1000' " Sales organization
ID 'VTWEG' FIELD '10' " Distribution channel
ID 'SPART' FIELD '00' " Division
ID 'ACTVT' FIELD '02'. " Activity: Change
IF sy-subrc <> 0.
MESSAGE e002(zmessages).
" 'No authorization for this sales organization'
RETURN.
ENDIF.

3. DUMMY for Optional Fields

" DUMMY = Field is not checked
AUTHORITY-CHECK OBJECT 'M_BEST_BSA'
ID 'ACTVT' FIELD '03' " Activity: Display
ID 'BSART' DUMMY. " Document type is not checked
IF sy-subrc = 0.
" User is allowed to display all document types
ENDIF.

4. Activity Codes (ACTVT)

" Standard activities
CONSTANTS:
c_actvt_create TYPE activ_auth VALUE '01',
c_actvt_change TYPE activ_auth VALUE '02',
c_actvt_display TYPE activ_auth VALUE '03',
c_actvt_delete TYPE activ_auth VALUE '06',
c_actvt_execute TYPE activ_auth VALUE '16'.
" Check with activity
DATA(lv_activity) = COND activ_auth(
WHEN gv_mode = 'CREATE' THEN c_actvt_create
WHEN gv_mode = 'CHANGE' THEN c_actvt_change
ELSE c_actvt_display
).
AUTHORITY-CHECK OBJECT 'Z_MYOBJECT'
ID 'ACTVT' FIELD lv_activity
ID 'ZFIELD' FIELD lv_value.
IF sy-subrc <> 0.
CASE lv_activity.
WHEN c_actvt_create.
MESSAGE 'No authorization to create' TYPE 'E'.
WHEN c_actvt_change.
MESSAGE 'No authorization to change' TYPE 'E'.
WHEN OTHERS.
MESSAGE 'No display authorization' TYPE 'E'.
ENDCASE.
ENDIF.

5. Create Authorization Class

CLASS zcl_authority_check DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ty_auth_result,
authorized TYPE abap_bool,
message TYPE string,
END OF ty_auth_result.
CLASS-METHODS: check_sales_org
IMPORTING iv_vkorg TYPE vkorg
iv_activity TYPE activ_auth
RETURNING VALUE(rs_result) TYPE ty_auth_result.
CLASS-METHODS: check_transaction
IMPORTING iv_tcode TYPE tcode
RETURNING VALUE(rv_auth) TYPE abap_bool.
CLASS-METHODS: check_custom_object
IMPORTING iv_field1 TYPE string
iv_field2 TYPE string
iv_activity TYPE activ_auth
RETURNING VALUE(rv_auth) TYPE abap_bool.
ENDCLASS.
CLASS zcl_authority_check IMPLEMENTATION.
METHOD check_sales_org.
AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
ID 'VKORG' FIELD iv_vkorg
ID 'VTWEG' DUMMY
ID 'SPART' DUMMY
ID 'ACTVT' FIELD iv_activity.
IF sy-subrc = 0.
rs_result-authorized = abap_true.
ELSE.
rs_result-authorized = abap_false.
rs_result-message = |No authorization for sales org { iv_vkorg }|.
ENDIF.
ENDMETHOD.
METHOD check_transaction.
AUTHORITY-CHECK OBJECT 'S_TCODE'
ID 'TCD' FIELD iv_tcode.
rv_auth = xsdbool( sy-subrc = 0 ).
ENDMETHOD.
METHOD check_custom_object.
AUTHORITY-CHECK OBJECT 'Z_CUSTOM_OBJ'
ID 'ZFIELD1' FIELD iv_field1
ID 'ZFIELD2' FIELD iv_field2
ID 'ACTVT' FIELD iv_activity.
rv_auth = xsdbool( sy-subrc = 0 ).
ENDMETHOD.
ENDCLASS.
" Usage
DATA(ls_auth) = zcl_authority_check=>check_sales_org(
iv_vkorg = '1000'
iv_activity = '02'
).
IF ls_auth-authorized = abap_false.
MESSAGE ls_auth-message TYPE 'E'.
ENDIF.

6. Authorization Check for Table Access

" S_TABU_DIS - Table authorization
DATA: lv_table TYPE tabname VALUE 'KNA1'.
" Determine table authorization group
SELECT SINGLE cclass FROM tddat
WHERE tabname = @lv_table
INTO @DATA(lv_auth_group).
AUTHORITY-CHECK OBJECT 'S_TABU_DIS'
ID 'DICBERCLS' FIELD lv_auth_group
ID 'ACTVT' FIELD '03'. " Display
IF sy-subrc <> 0.
MESSAGE |No authorization for table { lv_table }| TYPE 'E'.
ENDIF.

7. Check Organizational Levels

CLASS zcl_org_authority DEFINITION.
PUBLIC SECTION.
METHODS: check_org_levels
IMPORTING is_org_data TYPE ty_org_data
iv_activity TYPE activ_auth
RETURNING VALUE(rv_auth) TYPE abap_bool.
ENDCLASS.
CLASS zcl_org_authority IMPLEMENTATION.
METHOD check_org_levels.
" Company code
AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
ID 'BUKRS' FIELD is_org_data-bukrs
ID 'ACTVT' FIELD iv_activity.
IF sy-subrc <> 0.
rv_auth = abap_false.
RETURN.
ENDIF.
" Plant
AUTHORITY-CHECK OBJECT 'M_MATE_WRK'
ID 'WERKS' FIELD is_org_data-werks
ID 'ACTVT' FIELD iv_activity.
IF sy-subrc <> 0.
rv_auth = abap_false.
RETURN.
ENDIF.
" Storage location
AUTHORITY-CHECK OBJECT 'M_MATE_STO'
ID 'WERKS' FIELD is_org_data-werks
ID 'LGORT' FIELD is_org_data-lgort
ID 'ACTVT' FIELD iv_activity.
rv_auth = xsdbool( sy-subrc = 0 ).
ENDMETHOD.
ENDCLASS.

8. Authorization Check with Logging

CLASS zcl_auth_with_logging DEFINITION.
PUBLIC SECTION.
METHODS: check_and_log
IMPORTING iv_object TYPE xuobject
iv_field TYPE string
iv_value TYPE string
iv_activity TYPE activ_auth
RETURNING VALUE(rv_auth) TYPE abap_bool.
PRIVATE SECTION.
METHODS: log_auth_failure
IMPORTING iv_object TYPE xuobject
iv_field TYPE string
iv_value TYPE string
iv_activity TYPE activ_auth.
ENDCLASS.
CLASS zcl_auth_with_logging IMPLEMENTATION.
METHOD check_and_log.
" Dynamic authorization check
AUTHORITY-CHECK OBJECT iv_object
ID 'ACTVT' FIELD iv_activity
ID iv_field FIELD iv_value.
IF sy-subrc = 0.
rv_auth = abap_true.
ELSE.
rv_auth = abap_false.
log_auth_failure(
iv_object = iv_object
iv_field = iv_field
iv_value = iv_value
iv_activity = iv_activity
).
ENDIF.
ENDMETHOD.
METHOD log_auth_failure.
" Log to custom table
INSERT INTO zauth_log VALUES @( VALUE #(
timestamp = sy-datum && sy-uzeit
user = sy-uname
object = iv_object
field = iv_field
value = iv_value
activity = iv_activity
) ).
" Or Application Log
" See: Application Logging
ENDMETHOD.
ENDCLASS.

9. Check Authorizations for BAPI

FUNCTION z_bapi_customer_change.
*"----------------------------------------------------------------------
*" IMPORTING
*" VALUE(IV_KUNNR) TYPE KUNNR
*" VALUE(IS_DATA) TYPE TY_CUSTOMER_DATA
*" EXPORTING
*" VALUE(ET_RETURN) TYPE BAPIRET2_T
*"----------------------------------------------------------------------
" Authorization check
AUTHORITY-CHECK OBJECT 'F_KNA1_BUK'
ID 'BUKRS' FIELD is_data-bukrs
ID 'ACTVT' FIELD '02'.
IF sy-subrc <> 0.
APPEND VALUE bapiret2(
type = 'E'
id = 'ZMSG'
number = '001'
message = |No change authorization for company code { is_data-bukrs }|
message_v1 = is_data-bukrs
) TO et_return.
RETURN.
ENDIF.
" Change customer master...
ENDFUNCTION.

10. Check All Authorizations for an Object

" Check all values for which user is authorized
DATA: lt_values TYPE TABLE OF string.
" Determine sales organizations for which authorization exists
SELECT vkorg FROM tvko INTO TABLE @DATA(lt_vkorg).
LOOP AT lt_vkorg INTO DATA(lv_vkorg).
AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
ID 'VKORG' FIELD lv_vkorg
ID 'VTWEG' DUMMY
ID 'SPART' DUMMY
ID 'ACTVT' FIELD '03'.
IF sy-subrc = 0.
APPEND lv_vkorg TO lt_values.
ENDIF.
ENDLOOP.
WRITE: / 'Authorized sales organizations:'.
LOOP AT lt_values INTO DATA(lv_val).
WRITE: / lv_val.
ENDLOOP.

11. Analyze Authorization Object with SUIM

" Programmatically read authorizations of a user
DATA: lt_auth_values TYPE TABLE OF usvalues.
CALL FUNCTION 'SUSR_USER_AUTH_FOR_OBJ_GET'
EXPORTING
user_name = sy-uname
sel_object = 'V_VBAK_VKO'
TABLES
values = lt_auth_values
EXCEPTIONS
user_name_not_exist = 1
not_authorized = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc = 0.
LOOP AT lt_auth_values INTO DATA(ls_auth).
WRITE: / ls_auth-field, ls_auth-von, '-', ls_auth-bis.
ENDLOOP.
ENDIF.

12. Define Custom Authorization Object

" 1. Create authorization object in SU21:
" Name: Z_ORDERS
" Fields:
" - ACTVT (Activity)
" - ZREGION (custom field)
" - ZTYPE (custom field)
" 2. Usage in code:
AUTHORITY-CHECK OBJECT 'Z_ORDERS'
ID 'ACTVT' FIELD '02' " Change
ID 'ZREGION' FIELD 'EUROPE'
ID 'ZTYPE' FIELD 'SALES'.
IF sy-subrc <> 0.
MESSAGE 'No authorization for European sales orders' TYPE 'E'.
ENDIF.

13. RAP: Authorization Check in Behavior Definition

" Behavior Definition
managed implementation in class zbp_i_order unique;
define behavior for ZI_ORDER
{
// Static authorization check
authorization master ( instance )
create;
update;
delete;
}
" Behavior Implementation
CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations
RESULT result.
ENDCLASS.
CLASS lhc_order IMPLEMENTATION.
METHOD get_instance_authorizations.
READ ENTITIES OF zi_order IN LOCAL MODE
ENTITY order
FIELDS ( region order_type )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders).
LOOP AT lt_orders INTO DATA(ls_order).
" Update authorization
IF requested_authorizations-%update = if_abap_behv=>mk-on.
AUTHORITY-CHECK OBJECT 'Z_ORDERS'
ID 'ACTVT' FIELD '02'
ID 'ZREGION' FIELD ls_order-region
ID 'ZTYPE' FIELD ls_order-order_type.
DATA(lv_update_auth) = COND #(
WHEN sy-subrc = 0 THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized
).
ENDIF.
" Delete authorization
IF requested_authorizations-%delete = if_abap_behv=>mk-on.
AUTHORITY-CHECK OBJECT 'Z_ORDERS'
ID 'ACTVT' FIELD '06'
ID 'ZREGION' FIELD ls_order-region
ID 'ZTYPE' FIELD ls_order-order_type.
DATA(lv_delete_auth) = COND #(
WHEN sy-subrc = 0 THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized
).
ENDIF.
APPEND VALUE #(
%tky = ls_order-%tky
%update = lv_update_auth
%delete = lv_delete_auth
) TO result.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

14. Unit Test with Authorizations

CLASS ltcl_authority_test DEFINITION FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS: test_auth_check FOR TESTING.
ENDCLASS.
CLASS ltcl_authority_test IMPLEMENTATION.
METHOD test_auth_check.
" Test authorization check
" Note: In unit tests the executing user
" may have different authorizations
DATA(lv_auth) = zcl_authority_check=>check_transaction( 'SE38' ).
" Test depends on actual authorization
" Better: Use mock framework or test doubles
cl_abap_unit_assert=>assert_not_initial(
act = lv_auth
msg = 'Authorization for SE38 expected'
).
ENDMETHOD.
ENDCLASS.

15. Security Pattern for Critical Operations

CLASS zcl_secure_operations DEFINITION.
PUBLIC SECTION.
METHODS: delete_customer
IMPORTING iv_kunnr TYPE kunnr
RAISING zcx_not_authorized
zcx_business_error.
PRIVATE SECTION.
METHODS: check_delete_authority
IMPORTING iv_kunnr TYPE kunnr
RAISING zcx_not_authorized.
METHODS: check_no_open_items
IMPORTING iv_kunnr TYPE kunnr
RAISING zcx_business_error.
ENDCLASS.
CLASS zcl_secure_operations IMPLEMENTATION.
METHOD delete_customer.
" 1. Check authorization
check_delete_authority( iv_kunnr ).
" 2. Check business rules
check_no_open_items( iv_kunnr ).
" 3. Perform deletion
DELETE FROM kna1 WHERE kunnr = @iv_kunnr.
ENDMETHOD.
METHOD check_delete_authority.
" Read customer master for org data
SELECT SINGLE bukrs FROM knb1
WHERE kunnr = @iv_kunnr
INTO @DATA(lv_bukrs).
AUTHORITY-CHECK OBJECT 'F_KNA1_BUK'
ID 'BUKRS' FIELD lv_bukrs
ID 'ACTVT' FIELD '06'. " Delete
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_not_authorized
EXPORTING
textid = zcx_not_authorized=>delete_not_allowed
object = 'F_KNA1_BUK'
value = lv_bukrs.
ENDIF.
ENDMETHOD.
METHOD check_no_open_items.
" Check open items
SELECT COUNT(*) FROM bsid
WHERE kunnr = @iv_kunnr
INTO @DATA(lv_count).
IF lv_count > 0.
RAISE EXCEPTION TYPE zcx_business_error
EXPORTING
textid = zcx_business_error=>open_items_exist.
ENDIF.
ENDMETHOD.
ENDCLASS.

sy-subrc Values

ValueMeaning
0Authorization exists
4No authorization
8Too many fields specified
12Authorization object does not exist

Important Authorization Objects

ObjectDescription
S_TCODETransaction authorization
S_TABU_DISTable maintenance
S_DEVELOPDevelopment authorization
S_PROGRAMProgram execution
F_BKPF_BUKFI Company code
M_MATE_WRKMM Plant
V_VBAK_VKOSD Sales organization

Important Notes / Best Practice

  • Always check before critical operations (change, delete).
  • Use DUMMY for fields that are not relevant.
  • Standardize activities (01=Create, 02=Change, 03=Display, 06=Delete).
  • Provide meaningful error messages when authorization is missing.
  • Always check organizational levels (company code, plant, etc.).
  • Create custom objects for customer-specific requirements in SU21.
  • Log authorization failures for audit.
  • In RAP implement the Authorization Master methods.
  • Run unit tests with different user roles.
  • Combine with Exception Classes for structured error handling.