Verificaciones de autorizacion en ABAP: AUTHORITY-CHECK

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

Las verificaciones de autorizacion son esenciales para la seguridad de las aplicaciones SAP. Con AUTHORITY-CHECK verificas si un usuario tiene las autorizaciones necesarias para una accion.

Concepto basico

TerminoDescripcion
Objeto de autorizacionDefine campos verificables (ej. S_TCODE)
Campo de autorizacionCampo individual en el objeto (ej. TCD)
AutorizacionValores concretos para campos
RolColeccion de autorizaciones
PerfilAsignacion tecnica al usuario

Sintaxis

AUTHORITY-CHECK OBJECT 'NOMBRE_OBJETO'
ID 'CAMPO1' FIELD valor1
ID 'CAMPO2' FIELD valor2
ID 'CAMPO3' DUMMY.
IF sy-subrc <> 0.
" Sin autorizacion
ENDIF.

Ejemplos

1. Verificacion de autorizacion simple

" Verificar si el usuario puede ejecutar una transaccion
AUTHORITY-CHECK OBJECT 'S_TCODE'
ID 'TCD' FIELD 'VA01'.
IF sy-subrc <> 0.
MESSAGE e001(zmessages) WITH 'VA01'.
" 'No tienes autorizacion para la transaccion VA01'
RETURN.
ENDIF.
" Ejecutar transaccion
CALL TRANSACTION 'VA01'.

2. Verificar multiples campos

" Objeto de autorizacion con multiples campos
AUTHORITY-CHECK OBJECT 'V_VBAK_VKO'
ID 'VKORG' FIELD '1000' " Organizacion de ventas
ID 'VTWEG' FIELD '10' " Canal de distribucion
ID 'SPART' FIELD '00' " Division
ID 'ACTVT' FIELD '02'. " Actividad: Modificar
IF sy-subrc <> 0.
MESSAGE e002(zmessages).
" 'Sin autorizacion para esta organizacion de ventas'
RETURN.
ENDIF.

3. DUMMY para campos opcionales

" DUMMY = El campo no se verifica
AUTHORITY-CHECK OBJECT 'M_BEST_BSA'
ID 'ACTVT' FIELD '03' " Actividad: Visualizar
ID 'BSART' DUMMY. " Tipo de documento no se verifica
IF sy-subrc = 0.
" El usuario puede visualizar todos los tipos de documento
ENDIF.

4. Codigos de actividad (ACTVT)

" Actividades estandar
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'.
" Verificacion con actividad
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 'Sin autorizacion para crear' TYPE 'E'.
WHEN c_actvt_change.
MESSAGE 'Sin autorizacion para modificar' TYPE 'E'.
WHEN OTHERS.
MESSAGE 'Sin autorizacion para visualizar' TYPE 'E'.
ENDCASE.
ENDIF.

5. Crear clase de autorizacion

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 = |Sin autorizacion para org. ventas { 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.
" Uso
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. Verificacion de autorizacion para acceso a tablas

" S_TABU_DIS - Autorizacion de tabla
DATA: lv_table TYPE tabname VALUE 'KNA1'.
" Determinar grupo de autorizacion de la tabla
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'. " Visualizar
IF sy-subrc <> 0.
MESSAGE |Sin autorizacion para tabla { lv_table }| TYPE 'E'.
ENDIF.

7. Verificar niveles organizativos

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.
" Sociedad
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.
" Centro
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.
" Almacen
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. Verificacion de autorizacion con protocolo

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.
" Verificacion de autorizacion dinamica
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.
" Protocolo en tabla propia
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
) ).
" O Application Log
" Ver: Application Logging
ENDMETHOD.
ENDCLASS.

9. Verificar autorizaciones para 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
*"----------------------------------------------------------------------
" Verificacion de autorizacion
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 = |Sin autorizacion de modificacion para sociedad { is_data-bukrs }|
message_v1 = is_data-bukrs
) TO et_return.
RETURN.
ENDIF.
" Modificar maestro de clientes...
ENDFUNCTION.

10. Verificar todas las autorizaciones de un objeto

" Verificar todos los valores para los que el usuario tiene autorizacion
DATA: lt_values TYPE TABLE OF string.
" Determinar organizaciones de ventas para las que existe autorizacion
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: / 'Organizaciones de ventas autorizadas:'.
LOOP AT lt_values INTO DATA(lv_val).
WRITE: / lv_val.
ENDLOOP.

11. Analizar objeto de autorizacion con SUIM

" Leer autorizaciones de un usuario programaticamente
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. Definir objeto de autorizacion propio

" 1. Crear objeto de autorizacion en SU21:
" Nombre: Z_ORDERS
" Campos:
" - ACTVT (Actividad)
" - ZREGION (campo propio)
" - ZTYPE (campo propio)
" 2. Uso en el codigo:
AUTHORITY-CHECK OBJECT 'Z_ORDERS'
ID 'ACTVT' FIELD '02' " Modificar
ID 'ZREGION' FIELD 'EUROPE'
ID 'ZTYPE' FIELD 'SALES'.
IF sy-subrc <> 0.
MESSAGE 'Sin autorizacion para pedidos de venta europeos' TYPE 'E'.
ENDIF.

13. RAP: Verificacion de autorizacion en Behavior Definition

" Behavior Definition
managed implementation in class zbp_i_order unique;
define behavior for ZI_ORDER
{
// Verificacion de autorizacion estatica
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).
" Autorizacion de actualizacion
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.
" Autorizacion de eliminacion
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 con autorizaciones

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.
" Probar verificacion de autorizacion
" Nota: En Unit Test el usuario ejecutante
" posiblemente tiene otras autorizaciones
DATA(lv_auth) = zcl_authority_check=>check_transaction( 'SE38' ).
" Test dependiente de la autorizacion real
" Mejor: Usar framework de Mock o Testdoubles
cl_abap_unit_assert=>assert_not_initial(
act = lv_auth
msg = 'Se esperaba autorizacion para SE38'
).
ENDMETHOD.
ENDCLASS.

15. Patron de seguridad para operaciones criticas

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. Verificar autorizacion
check_delete_authority( iv_kunnr ).
" 2. Verificar reglas de negocio
check_no_open_items( iv_kunnr ).
" 3. Ejecutar eliminacion
DELETE FROM kna1 WHERE kunnr = @iv_kunnr.
ENDMETHOD.
METHOD check_delete_authority.
" Leer maestro de clientes para datos org.
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'. " Eliminar
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.
" Verificar partidas abiertas
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.

Valores de sy-subrc

ValorSignificado
0Autorizacion existente
4Sin autorizacion
8Demasiados campos especificados
12Objeto de autorizacion no existe

Objetos de autorizacion importantes

ObjetoDescripcion
S_TCODEAutorizacion de transaccion
S_TABU_DISMantenimiento de tablas
S_DEVELOPAutorizacion de desarrollo
S_PROGRAMEjecucion de programas
F_BKPF_BUKFI Sociedad
M_MATE_WRKMM Centro
V_VBAK_VKOSD Organizacion de ventas

Notas importantes / Mejores practicas

  • Siempre verificar antes de operaciones criticas (Modificar, Eliminar).
  • Usar DUMMY para campos que no son relevantes.
  • Estandarizar actividades (01=Crear, 02=Modificar, 03=Visualizar, 06=Eliminar).
  • Mensajes de error descriptivos cuando falta autorizacion.
  • Siempre verificar niveles organizativos (Sociedad, Centro, etc.).
  • Crear objetos propios para requisitos especificos del cliente en SU21.
  • Protocolo de errores de autorizacion para auditoria.
  • En RAP implementar los metodos Authorization Master.
  • Realizar Unit Tests con diferentes roles de usuario.
  • Combinar con Clases de excepcion para manejo estructurado de errores.