ABAP Authorization Checks: AUTHORITY-CHECK

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Berechtigungsprüfungen sind essenziell für die Sicherheit von SAP-Anwendungen. Mit AUTHORITY-CHECK prüfen Sie, ob ein Benutzer die erforderlichen Berechtigungen für eine Aktion besitzt.

Grundkonzept

BegriffBeschreibung
BerechtigungsobjektDefiniert prüfbare Felder (z.B. S_TCODE)
BerechtigungsfeldEinzelnes Feld im Objekt (z.B. TCD)
BerechtigungKonkrete Werte für Felder
RolleSammlung von Berechtigungen
ProfilTechnische Zuweisung zum Benutzer

Syntax

AUTHORITY-CHECK OBJECT 'OBJEKT_NAME'
ID 'FELD1' FIELD wert1
ID 'FELD2' FIELD wert2
ID 'FELD3' DUMMY.
IF sy-subrc <> 0.
" Keine Berechtigung
ENDIF.

Beispiele

1. Einfache Berechtigungsprüfung

" Prüfen ob Benutzer Transaktion ausführen darf
AUTHORITY-CHECK OBJECT 'S_TCODE'
ID 'TCD' FIELD 'VA01'.
IF sy-subrc <> 0.
MESSAGE e001(zmessages) WITH 'VA01'.
" 'Sie haben keine Berechtigung für Transaktion VA01'
RETURN.
ENDIF.
" Transaktion ausführen
CALL TRANSACTION 'VA01'.

2. Mehrere Felder prüfen

" Berechtigungsobjekt mit mehreren Feldern
AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
ID 'VKORG' FIELD '1000' " Verkaufsorganisation
ID 'VTWEG' FIELD '10' " Vertriebsweg
ID 'SPART' FIELD '00' " Sparte
ID 'ACTVT' FIELD '02'. " Aktivität: Ändern
IF sy-subrc <> 0.
MESSAGE e002(zmessages).
" 'Keine Berechtigung für diese Verkaufsorganisation'
RETURN.
ENDIF.

3. DUMMY für optionale Felder

" DUMMY = Feld wird nicht geprüft
AUTHORITY-CHECK OBJECT 'M_BEST_BSA'
ID 'ACTVT' FIELD '03' " Aktivität: Anzeigen
ID 'BSART' DUMMY. " Belegart wird nicht geprüft
IF sy-subrc = 0.
" Benutzer darf alle Belegarten anzeigen
ENDIF.

4. Aktivitätscodes (ACTVT)

" Standardaktivitäten
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'.
" Prüfung mit Aktivität
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 'Keine Berechtigung zum Anlegen' TYPE 'E'.
WHEN c_actvt_change.
MESSAGE 'Keine Berechtigung zum Ändern' TYPE 'E'.
WHEN OTHERS.
MESSAGE 'Keine Anzeigeberechtigung' TYPE 'E'.
ENDCASE.
ENDIF.

5. Berechtigungsklasse erstellen

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 = |Keine Berechtigung für VKOrg { 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.
" Verwendung
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. Berechtigungsprüfung für Tabellenzugriff

" S_TABU_DIS - Tabellenberechtigung
DATA: lv_table TYPE tabname VALUE 'KNA1'.
" Tabellenberechtigungsgruppe ermitteln
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'. " Anzeigen
IF sy-subrc <> 0.
MESSAGE |Keine Berechtigung für Tabelle { lv_table }| TYPE 'E'.
ENDIF.

7. Organisationsebenen prüfen

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.
" Buchungskreis
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.
" Werk
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.
" Lagerort
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. Berechtigungsprüfung mit Protokollierung

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.
" Dynamische Berechtigungsprüfung
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.
" Protokollierung in eigene Tabelle
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
) ).
" Oder Application Log
" Siehe: Application Logging
ENDMETHOD.
ENDCLASS.

9. Berechtigungen für BAPI prüfen

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
*"----------------------------------------------------------------------
" Berechtigungsprüfung
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 = |Keine Änderungsberechtigung für Buchungskreis { is_data-bukrs }|
message_v1 = is_data-bukrs
) TO et_return.
RETURN.
ENDIF.
" Kundenstamm ändern...
ENDFUNCTION.

10. Alle Berechtigungen eines Objekts prüfen

" Alle Werte prüfen, für die Benutzer berechtigt ist
DATA: lt_values TYPE TABLE OF string.
" Verkaufsorganisationen ermitteln, für die Berechtigung besteht
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: / 'Berechtigte Verkaufsorganisationen:'.
LOOP AT lt_values INTO DATA(lv_val).
WRITE: / lv_val.
ENDLOOP.

11. Berechtigungsobjekt mit SUIM analysieren

" Programmatisch Berechtigungen eines Users lesen
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. Eigenes Berechtigungsobjekt definieren

" 1. Berechtigungsobjekt in SU21 anlegen:
" Name: Z_ORDERS
" Felder:
" - ACTVT (Aktivität)
" - ZREGION (eigenes Feld)
" - ZTYPE (eigenes Feld)
" 2. Verwendung im Code:
AUTHORITY-CHECK OBJECT 'Z_ORDERS'
ID 'ACTVT' FIELD '02' " Ändern
ID 'ZREGION' FIELD 'EUROPE'
ID 'ZTYPE' FIELD 'SALES'.
IF sy-subrc <> 0.
MESSAGE 'Keine Berechtigung für europäische Verkaufsaufträge' TYPE 'E'.
ENDIF.

13. RAP: Berechtigungsprüfung in Behavior Definition

" Behavior Definition
managed implementation in class zbp_i_order unique;
define behavior for ZI_ORDER
{
// Statische Berechtigungsprüfung
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-Berechtigung
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-Berechtigung
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 mit Berechtigungen

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.
" Berechtigungsprüfung testen
" Hinweis: Im Unit Test hat der ausführende User
" möglicherweise andere Berechtigungen
DATA(lv_auth) = zcl_authority_check=>check_transaction( 'SE38' ).
" Test abhängig von tatsächlicher Berechtigung
" Besser: Mock-Framework oder Testdoubles verwenden
cl_abap_unit_assert=>assert_not_initial(
act = lv_auth
msg = 'Berechtigung für SE38 erwartet'
).
ENDMETHOD.
ENDCLASS.

15. Sicherheitsmuster für kritische Operationen

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. Berechtigung prüfen
check_delete_authority( iv_kunnr ).
" 2. Business-Regeln prüfen
check_no_open_items( iv_kunnr ).
" 3. Löschung durchführen
DELETE FROM kna1 WHERE kunnr = @iv_kunnr.
ENDMETHOD.
METHOD check_delete_authority.
" Kundenstamm lesen für Org-Daten
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'. " Löschen
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.
" Offene Posten prüfen
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 Werte

WertBedeutung
0Berechtigung vorhanden
4Keine Berechtigung
8Zu viele Felder angegeben
12Berechtigungsobjekt nicht vorhanden

Wichtige Berechtigungsobjekte

ObjektBeschreibung
S_TCODETransaktionsberechtigung
S_TABU_DISTabellenpflege
S_DEVELOPEntwicklungsberechtigung
S_PROGRAMProgrammausführung
F_BKPF_BUKFI Buchungskreis
M_MATE_WRKMM Werk
V_VBAK_VKOSD Verkaufsorganisation

Wichtige Hinweise / Best Practice

  • Immer prüfen vor kritischen Operationen (Ändern, Löschen).
  • DUMMY für Felder verwenden, die nicht relevant sind.
  • Aktivitäten standardisieren (01=Anlegen, 02=Ändern, 03=Anzeigen, 06=Löschen).
  • Aussagekräftige Fehlermeldungen bei fehlender Berechtigung.
  • Organisationsebenen immer mitprüfen (Buchungskreis, Werk, etc.).
  • Eigene Objekte für kundenspezifische Anforderungen in SU21 anlegen.
  • Protokollierung von Berechtigungsfehlern für Audit.
  • In RAP die Authorization Master-Methoden implementieren.
  • Unit Tests mit verschiedenen Benutzerrollen durchführen.
  • Kombinieren Sie mit Exception Classes für strukturierte Fehlerbehandlung.