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
| Term | Description |
|---|---|
| Authorization Object | Defines checkable fields (e.g., S_TCODE) |
| Authorization Field | Single field in the object (e.g., TCD) |
| Authorization | Concrete values for fields |
| Role | Collection of authorizations |
| Profile | Technical 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 authorizationENDIF.Examples
1. Simple Authorization Check
" Check if user is authorized to execute transactionAUTHORITY-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 transactionCALL TRANSACTION 'VA01'.2. Check Multiple Fields
" Authorization object with multiple fieldsAUTHORITY-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 checkedAUTHORITY-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 typesENDIF.4. Activity Codes (ACTVT)
" Standard activitiesCONSTANTS: 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 activityDATA(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.
" UsageDATA(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 authorizationDATA: lv_table TYPE tabname VALUE 'KNA1'.
" Determine table authorization groupSELECT 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 authorizedDATA: lt_values TYPE TABLE OF string.
" Determine sales organizations for which authorization existsSELECT 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 userDATA: 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 Definitionmanaged implementation in class zbp_i_order unique;
define behavior for ZI_ORDER{ // Static authorization check authorization master ( instance )
create; update; delete;}
" Behavior ImplementationCLASS 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
| Value | Meaning |
|---|---|
| 0 | Authorization exists |
| 4 | No authorization |
| 8 | Too many fields specified |
| 12 | Authorization object does not exist |
Important Authorization Objects
| Object | Description |
|---|---|
S_TCODE | Transaction authorization |
S_TABU_DIS | Table maintenance |
S_DEVELOP | Development authorization |
S_PROGRAM | Program execution |
F_BKPF_BUK | FI Company code |
M_MATE_WRK | MM Plant |
V_VBAK_VKO | SD 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.