Skip to Content

In my recent work I came across some questions if or how it could be achieved to check if a user with Finance/Controlling Authorisations can see employees of their cost centres or profit centres only.

 

SAP HR security is mainly based on the organisational assignment of employees  which is stored in Infotype 0001 of the employee master record. Additionally a HR organisational structure check can be called  to find out if the user has access to the part of the structure of the employee. The first option will mainly work with SAP authorisation object P_ORGIN. The second option however requires to switch on and to maintain at least HR structural authorisations.

 

A look at P_ORGIN will quickly show that there is no field cost centre or profit centre available. And who says that the HR organisational structure will match the Cost Centre or Profit Centre hierarchy of the company. There might be a manager  who has responsibility for a cost centre but their cost centre might not be the only one with employees in a certain HR org unit.

 

Just a few weeks ago I found some SDN member with a quite similar issue in the forum. Re: Authorizations for report PC00_M99_CIPE  by field PayrollArea

 

He was after a solution to check whether the user has access to a certain Payroll Area. Now the Payroll Area is not included in P_ORGIN and it will be hard to find a HR authorisation object which will do the check.

 

But SAP is prepared for these sorts of specific needs in the area of HR security. SAP provided a BAdI. BAdIs are places in the SAP standard which allow to add customer specific logic without changing standard. Rich Heilman provided a good wiki on that: http://wiki.sdn.sap.com/wiki/display/ABAP/Enhancements+and+Modifications+-+BADI,+Enhancement+Framework,+User+Exits,+BTE

 

The  BAdI which will help us to enhance the HR Authorisations is HRPAD00AUTH_CHECK

 

There are some things we should know about the BAdI when we start using it. The implementation will switch of the HR standard authorisation checks but no worries they can easily be called from our BAdI again. That is something what I would recommend. When the BAdI will be switched on always start with the implementation of every method and call the SAP standard authorisation class method with the same name.
Every method!
Once this is done select the method you want to enhance and call additional checks in the method.
For example method ‘CHECK_AUTHORIZATION’. Here we can implement additional checks for certain and critical infotype records. In that case we could call the SAP standard authorisation check first. If standard checks are passed we can check additional customer specific criterias for the user who tries to get access to that specific infotype. Our customer check could for example look up the employee assignment to a cost centre. With the employee cost centre it could then call the authorisation check on authorisation object K_CSKS.

 

How good is that? That example will allow to check authorisations for a cost centre of an employee when accessing HR data. Even more, that example would do the check only for certain infotypes. And last but not least as long as we call the check of the authorisation object in the good old ABAP standard way, the result will show up in a security trace (transaction ST01).

 

You can think about many options which SAP provided us with that BAdI. The doors are open for all sorts customer enhancements of HR security. It is fantastic.

 

As mentioned earlier there was a question in the SDN forum about an authorisation check on the Payroll area. Following I will provide the screen shots of my answer. That will allow to follow the idea I have described above. Maybe some of you might find that there are too many screen shots in here. But I think  that everybody should get the chance to read through and to understand. I like to enable people to start trying and playing even if they have not used BAdIs and ABAP as much.

 

The screen shots will document 2 topics which might help to get started on new ideas. They will explain how we can easily create customer authorisation objects and related to the topic of the blog they will show a really simple implementation of the BAdI.

 

Creation of an new authorisation object – Transaction SU21

Overview SU21

In SU21 all authorisation classes will be displayed as folders and the authorisation objects are displayed within these folders.

The creation of own authorisation objects will start with the creation of a new authorisation class.

Click icon –  Create Authorisation and create a new Authorisation Object Class.

 Authorisation Class

 

The new authorisation class will be shown in the tree structure.

Now the class should be highlighted and the Create Icon must be clicked again to create the new Authorisation Object.

Overview with new auth class 

Authorisation Object

After the new authorisation object is created it will appear in the folder of the authorisation object class. 

New Auth class and Object

 

Now it is time to implement the BAdI HRPAD00AUTH_CHECK  – transaction SE19

Overview SE19

Click on icon Create Implementation Create Button. The BAdI Implementation will prompt for a name.

BAdI Create Start Screen

Click on TAB Interfaces at the BAdI implementation screen.

BAdI Main Screen

The Interface TAB shows the name of the Implementing ABAP class.

A Double Click on the Implementing Class name will navigate to the ABAP class builder.

BAdI Interface Tab

As described earlier I would always recommend to call the SAP standard authorisation checks. To do so, it will be required to call the SAP standard logic from another class.

Therefore the creation of a new class attribute is required. I called it

SAP_STANDARD_AUTH with TYPE REF TO CL_HRPAD00_CHECK_STD as shown below.

Implementing Class 01

The new attribute will be used to keep an instance of the SAP standard authorisation class. The Instance will be created in method IF_EX_CL_HRPAD00_CHECK_STD~DELAYED_CONSTRUCTOR

Implementing Class 02

The method will require the following coding block to create the instance of the SAP standard authorisation class.

METHOD if_ex_hrpad00auth_check~delayed_constructor.

CREATE OBJECT sap_standard_auth.

ENDMETHOD.

Implementing Class 03

The instance should now always exist when methods of the BAdI will be called.

Implementing Class 04

Back at the class overview of all methods I will show an example implementation of one method. The same must be repeated for every single method of the class.

To start double click on a method.

Implementing Class 05

Start by copying the following code between Method IF…

And Endmethod.

IF sap_standard_auth IS INITIAL.

CREATE OBJECT sap_standard_auth.

ENDIF.

 

IF sy-subrc = 1.

RAISE invalid.

ELSEIF sy-subrc = 2.

RAISE internal_error.

ENDIF.

Implementing Class 07

The part where I check if we have an existing instance of SAP_STANDARD_AUTH might be redundant. But I think it is a good idea to avoid any unexpected errors. Now back to the code.

The cursor should be placed before the last IF clause and then we start to use the ABAP Pattern Function.

Click the Pattern Icon.  Pattern Button The ABAP Object Pattern will be helpful to call the SAP standard authorisation class methods.

Pattern

The method name in the pattern screen and the method we are working on must match.

Pattern 02

 

Implementing Class 08

The commented code should be uncommented. The parameter names will be the same.

Implementing Class 09

Remember the same should be done for all methods except the DELAYED_CONSTRUCTOR of course.

Once that has all been done, the building of the customer logic can begin. In my example I will demonstrate now a very simple check on the new authorisation object.

The example however is not the end of what is possible. Surely many other employee related data could be read and checked here. The conditions for the checks can be built creative as well. For example could checks just be done if certain infotypes are requested by users etc.

The check on my new object will go into Interface Method: CHECK_AUTHORIZATION

Implementing Class 10

In there I add some code just before the endmethod statement. The customer check will just be done if the standard checks have been passed before. In the example I run the checks only for a certain transaction. 

CHECK is_authorized EQ ‘X’.

CHECK sy-tcode EQ ‘PC00_M99_CIPE’.

DATA : l_abkrs TYPE abkrs.

SELECT SINGLE abkrs FROM pa0001 INTO l_abkrs

WHERE pernr EQ pernr AND

endda GE sy-datum AND

 begda LE sy-datum.

IF sy-subrc IS INITIAL.

AUTHORITY-CHECK OBJECT ‘Z_PY_AREA’

ID ‘ABKRS’

FIELD l_abkrs.

IF sy-subrc IS NOT INITIAL.

CLEAR is_authorized.

ENDIF.

ENDIF.

 

Implementing Class 11

And that is all. By the way the Authorisation Check on the new authorisation object has been build using the ABAP editor pattern function again. 

It is time to activate the Implementing Class of the BAdI.

Clicking the BACK button will take us back to the BAdI.

Implementing Class 12

Finally the BAdI must be activated.

BAdI Activation Final

 

That is it. Now all is said and customer authorisation checks in HR should never be an issue again. 🙂

To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

  1. Chris Paine
    Excellent stuff Karsten, and a great effort for your first blog.

    I note that you just create a reference to the standard implementation using “create object” but do this within the delayed constructor method. Why do you not do this in the constructor of the class?

    Just interested!

    Cheers,

    Chris

    (0) 
    1. Karsten Arold Post author
      Thank you Chris,

      it is great to get a good feedback from an experienced blogger and colleague.

      And sure you are right we could create a constructor in the implementing class of the BAdI.

      I just did not do that because the interface comes with the delayed constructor method which does the same for me.

      And I also found a SAP implementation of that BAdI which is delivered inactive. The BAdI implementation is called HRPADUN_AAP_RPAU_CHK.
      The implementing class in that example also uses the delayed constructor method.

      Cheers,
      Karsten

      (0) 
  2. Corwin Slack
    This is very helpful. Since I am a novice at object oriented programming I wonder if you could suggest a proper approach to implementing checks when object P_ABAP has a value of 1 for field COARS. See http://help.sap.com/saphelp_470/helpdata/en/e0/bdb83b5b831f3be10000000a114084/content.htm.

    It seems from examining some usage of this object that function module HR_SET_CPROG_COARS is called which tests the object for COARS = 1 and then initializes the badi using the context FUNCT. How do I refer to that context properly? Or am I all mixed up?
    Thanks

    (0) 
  3. Corwin Slack
    I did my implementation following the basic model in the SAP example BAdI HRPAD00AUTH_CHECK implementation – HR security enhancements in SAP standard  but I didn’t implement a constructor class and put this logic in the delayed constructor method:

    AUTHORITY-CHECK OBJECT ‘P_ABAP’
               ID ‘REPID’ FIELD repid
               ID ‘COARS’ FIELD ‘1’.

      if sy-subrc = 0.
        CREATE OBJECT a_auth_check type  CL_HRPAD00AUTH_CHECK_FAST.
      else.
        CREATE OBJECT a_auth_check type  CL_HRPAD00AUTH_CHECK_STD.
    endif.

    I have basically unit tested this and it seems to work. Comments and critique welcomed.

    (0) 
    1. Corwin Slack
      I should have said “didn’t implement a contractor method”. It appears that this delayed-constructor was created for just this scenario because the authorization check for P_ABAP with COARS = 1 calls the delated constructor if the authorization passes.
      (0) 
  4. Sunil Sankar

    Hello,

    I have implemented BADI but it is not getting triggered from LDB – PNPCE. Do we need to modify authorization object P_ABAP which is checked in DBPNP_PNPCE_AUTH_FORMS  subroutine – PRECHECK_AUTHORITY,

     

    (0) 

Leave a Reply