Disabling Authorization Checks in an ABAP Program

You could talk a lot about authorizations in SAP HCM. It's a rather broad topic, and I believe a single post isn’t enough to do it justice. So I won’t cover that extensively here.

See: Authorizations for Human Resources

The topic of this article relates to situations where it is necessary to disable authorization checks (both structural and general authorizations). Disabling authorizations in ABAP programs is done in places where data is read from infotypes (PA or OM), followed by displaying the results on the screen. This may be needed when a user lacks access to a particular infotype or has a structural profile that doesn't include the objects used in the report selection. Often, for various reasons, extending their authorizations is not possible — but the report is important and useful. So what can be done?

Initial Data

Let’s consider a simple example. We have a user DEMO_USER1 whose role includes the authorization object P_ORGIN with the following values:

In addition to P_ORGIN (which gives access to infotype 0001 - Organizational Assignment), the role includes PLOG, which contains several infotypes for object type OOrganizational Unit.

On top of that, the user is assigned a structural profile that allows viewing only objects of type OOrganizational Unit.

Let’s just say the authorizations are not very "extensive."

Example: Program without Disabled Authorization Checks

We write a simple program to read infotype 0002 – Personal Data – and infotype 1000 – Object for object type SPosition, without disabling the authorization checks.

REPORT zdemo_auth.
PARAMETERS: s_pernr TYPE prelp-pernr,
            o_objid TYPE plog-objid.
 
DATA: lt_pa0002 TYPE TABLE OF p0002,
      ls_pa0002 TYPE pa0002,
      lt_1000 type TABLE OF p1000.
 
FIELD-SYMBOLS:  TYPE p0002.
 
 
CLEAR lt_pa0002[].
CALL FUNCTION 'HR_READ_INFOTYPE'
  EXPORTING
    pernr           = s_pernr
    infty           = '0002'
    begda           = '19000101' "sy-datum
    endda           = '99991231' "sy-datum
  TABLES
    infty_tab       = lt_pa0002
  EXCEPTIONS
    infty_not_found = 1
    OTHERS          = 2.
 
clear lt_1000[].
CALL FUNCTION 'RH_READ_INFTY_1000'
 EXPORTING
*   AUTHORITY              = 'DISP'
*   WITH_STRU_AUTH         = 'X'
   PLVAR                  = '01'
   OTYPE                  = 'S'
   OBJID                  = o_objid
*   ISTAT                  = ' '
*   EXTEND                 = 'X'
*   BEGDA                  = '19000101'
*   ENDDA                  = '99991231'
*   CONDITION              = '00000'
*   SORT                   = 'X'
  TABLES
    i1000 =               lt_1000
*   OBJECTS                =
 EXCEPTIONS
   NOTHING_FOUND          = 1
   WRONG_CONDITION        = 2
   WRONG_PARAMETERS       = 3
   OTHERS                 = 4
.
 
IF sy-subrc EQ 0.
 
  READ TABLE lt_pa0002 ASSIGNING  WITH KEY pernr = s_pernr.
  IF  IS ASSIGNED.
    WRITE / -pernr .
    WRITE / -vorna.
    WRITE / -nachn.
  ELSE.
    WRITE / '2nd select'.
    WRITE 'nothing to select!'.
 
  ENDIF.
ENDIF.
WRITE 'nothing to select!'.

Running the program:

0:00
/0:37

With these initial authorizations, the tables lt_pa0002 and lt_1000 remain empty, which is logical given the user's limited access.

Example: Program with Disabled Authorization Checks

Now let’s write a version of the program where authorization checks are disabled. To do this, we call two function modules at the beginning:

REPORT zdemo_auth.
PARAMETERS: s_pernr TYPE prelp-pernr,
            o_objid TYPE plog-objid.
 
DATA: lt_pa0002 TYPE TABLE OF p0002,
      ls_pa0002 TYPE pa0002,
      lt_1000   TYPE TABLE OF p1000.
 
FIELD-SYMBOLS:  TYPE p0002.
 
CALL FUNCTION 'RH_AUTHORITY_CHECK_OFF'.
CALL FUNCTION 'HR_READ_INFOTYPE_AUTHC_DISABLE'.
 
 
CLEAR lt_pa0002[].
CALL FUNCTION 'HR_READ_INFOTYPE'
  EXPORTING
    pernr           = s_pernr
    infty           = '0002'
    begda           = '19000101' "sy-datum
    endda           = '99991231' "sy-datum
  TABLES
    infty_tab       = lt_pa0002
  EXCEPTIONS
    infty_not_found = 1
    OTHERS          = 2.
 
CLEAR lt_1000[].
CALL FUNCTION 'RH_READ_INFTY_1000'
  EXPORTING
*   AUTHORITY        = 'DISP'
*   WITH_STRU_AUTH   = 'X'
    plvar            = '01'
    otype            = 'S'
    objid            = o_objid
*   ISTAT            = ' '
*   EXTEND           = 'X'
*   BEGDA            = '19000101'
*   ENDDA            = '99991231'
*   CONDITION        = '00000'
*   SORT             = 'X'
  TABLES
    i1000            = lt_1000
*   OBJECTS          =
  EXCEPTIONS
    nothing_found    = 1
    wrong_condition  = 2
    wrong_parameters = 3
    OTHERS           = 4.
 
IF sy-subrc EQ 0.
 
  READ TABLE lt_pa0002 ASSIGNING  WITH KEY pernr = s_pernr.
  IF  IS ASSIGNED.
    WRITE / -pernr .
    WRITE / -vorna.
    WRITE / -nachn.
  ELSE.
    WRITE / '2nd select '.
    WRITE 'nothing to select!'.
 
  ENDIF.
ENDIF.
 
CALL FUNCTION 'RH_AUTHORITY_CHECK_ON'.

Note: After disabling structural authorization checks and retrieving the needed data, you must re-enable the checks using RH_AUTHORITY_CHECK_ON. For infotype reads, re-enabling is not necessary, since checks are automatically re-activated after reading.

Testing:

0:00
/0:33

As you can see, this time the tables lt_pa0002 and lt_1000 are populated with data — even though they were empty in the earlier version of the program.

Confirmation: Authorization Check Reactivation

To confirm that the read authorization check is automatically re-enabled, let’s run this version of the program:

REPORT zdemo_auth.
PARAMETERS: s_pernr TYPE prelp-pernr,
            o_objid TYPE plog-objid.
 
DATA: lt_pa0002 TYPE TABLE OF p0002,
      ls_pa0002 TYPE pa0002,
      lt_1000   TYPE TABLE OF p1000.
 
FIELD-SYMBOLS:  TYPE p0002.
 
CALL FUNCTION 'RH_AUTHORITY_CHECK_OFF'.
CALL FUNCTION 'HR_READ_INFOTYPE_AUTHC_DISABLE'.
 
 
CLEAR lt_pa0002[].
CALL FUNCTION 'HR_READ_INFOTYPE'
  EXPORTING
    pernr           = s_pernr
    infty           = '0002'
    begda           = '19000101' "sy-datum
    endda           = '99991231' "sy-datum
  TABLES
    infty_tab       = lt_pa0002
  EXCEPTIONS
    infty_not_found = 1
    OTHERS          = 2.
 
CLEAR lt_1000[].
CALL FUNCTION 'RH_READ_INFTY_1000'
  EXPORTING
*   AUTHORITY        = 'DISP'
*   WITH_STRU_AUTH   = 'X'
    plvar            = '01'
    otype            = 'S'
    objid            = o_objid
*   ISTAT            = ' '
*   EXTEND           = 'X'
*   BEGDA            = '19000101'
*   ENDDA            = '99991231'
*   CONDITION        = '00000'
*   SORT             = 'X'
  TABLES
    i1000            = lt_1000
*   OBJECTS          =
  EXCEPTIONS
    nothing_found    = 1
    wrong_condition  = 2
    wrong_parameters = 3
    OTHERS           = 4.
 
IF sy-subrc EQ 0.
 
  READ TABLE lt_pa0002 ASSIGNING  WITH KEY pernr = s_pernr.
  IF  IS ASSIGNED.
*    WRITE / -pernr .
*    WRITE / -vorna.
*    WRITE / -nachn.
  ELSE.
    WRITE / '2nd select'.
    WRITE 'nothing to select!'.
 
  ENDIF.
ENDIF.
 
CALL FUNCTION 'RH_AUTHORITY_CHECK_ON'.
 
 
CLEAR lt_pa0002[].
CALL FUNCTION 'HR_READ_INFOTYPE'
  EXPORTING
    pernr           = s_pernr
    infty           = '0002'
    begda           = '19000101' "sy-datum
    endda           = '99991231' "sy-datum
  TABLES
    infty_tab       = lt_pa0002
  EXCEPTIONS
    infty_not_found = 1
    OTHERS          = 2.
 
IF lt_pa0002 is INITIAL.
  write 'nothing found!'.
ENDIF.

Notice: The lt_pa0002 table is filled at the beginning when checks are off, but the second call returns it empty — demonstrating that the check is automatically restored.

P.S. Please don’t judge the code quality too harshly. I meant no harm.