Quantcast
Channel: SCN : Document List - SAP Business Warehouse
Viewing all articles
Browse latest Browse all 1574

Dynamic Security Using OrgUnit Hierarchy

$
0
0

1       Objective

Maintaining security roles for large group of end users is always a challenging task. Hence it is required to develop solution with dynamic reporting security. In this case security requirements are based on OrgUnit hierarchy hence solution is for BW reports based on OrgUnit hierarchy.

Main idea is if A OrgUnit is assigned to user U1, then he should be able to access data of this OrgUnit & all child OrgUnits.

 

2       Brief Overview of Solution

Following are the parts of solution for making reporting security dynamic:

Z Table in ECC

This is required for maintaining ad-hoc OrgUnit assignments for accessing data for additional OrgUnits temporarily. This Z table will be loaded in a DSO in BW via table based datasource.

Extractor for OrgUnit Assignments

This extractor will bring OrgUnit assignments from HRP1001 & PA0001 for two type of users. HRP1001 will give OrgUnit assignments of users who are incharge of specific OrgUnits & PA0001 (Only specific designations will be considered based on requirements) will provide OrgUnit assignments of specific employees.

DSO in BW

This DSO will store data from two datasources mentioned above. This DSO will be referred by BW queries on run time to manage security.

 

BEx Variables

For making this dynamic security work, 2 Variables are added on OrgUnit:

       Input Ready

This variable V1 is used in “Default Values” section in filter pane. For this variable we have implemented a standard BADI for restricting F4 help values based on security.

       Customer Exit (No Input Ready)

This variable V2 is used in “Characteristic Restrictions” section of filter pane. It is customer exit variable, non-ready to input and to be processes in i_Step = 2. This variable will read values from other OrgUnit input ready variable and following is its logic flow:

If V1 variable is kept blank, this customer exit will be populated with authorized values of OrgUnit for the current user. Else if something is selected in V1, it will be validated in V2 and processed accordingly. More details in following sections of the document.

 

3 Z Table in ECC

This Z table is required to maintain ad-hoc OrgUnit assignments for reporting data at higher levels. For e.g. an end user may need to report data to (C level or Partner level) sometimes, for that he may need access to reports on OrgUnits which are not assigned to him in actual OrgUnit hierarchy in ECC, in these cases that user will be assigned required OrgUnits for specific period of time.

Maintenance generator is created for the table and table will be maintained via tcode and tcode will be assigned in security roles of specific people of application support team only.

Following is the structure of the table:

  Ztablw.png

Here, start & end date will restrict the access to specific ad-hoc OrgUnit assignment to specific period of time.

 

 

3.1 Tcode for table maintenance

Maintenance Generator Created for table for maintenance followed by creation of tcode for its maintenance in SE93:

  3_1.png

 

There is a table based generic datasource on this table.

4       Extractor for OrgUnit Assignments

This is a function module based generic datasource, based on client specific OrgUnit configuration it queries on HRP1001 table with filters on otype, sclas, rsign & relat to bring one set of users & corresponding OrgUnit assignments. Second set of reporting users is derived based on PA0001 based on senior executives or partners.

4.1 Extract structure for this datasource

4_1.png

 

 

4.2 Code Snippets

4.2.1       Starting Select Query

  4_2_1.png

 

4.2.2       Middle Part 1

  4_2_2.png

 

4.2.3       Middle Part 2

4_2_3.png

 

4.2.4       Last Part

4_2_4.png

 

5 DSO in BW

DSO in BW is mapped from both the datasources discussed in sections 3 & 4.

5.1 DSO Structure

  5_1.png

 

6 BEx Variables

6.1 Input Ready Variable

We have implemented BADI for restricting F4 help values of this variables based on current user executing the report via lookup on security DSO. This variable is used in “Default Values” section of fiter pane.

6.1.1 Location of BADI

SPRO >> SAP NETWEAVER >> Business Warehouse >> Enhancements >> BAdI: Restricting the Value Help in the Variables Screen


6.1.2 Process of Implementing BADI for F4 Help Restriction

 

6_1_2.png

Clicking on highlighted part of above screen shot will take you to following screen:

6_1_2_b.png

 

Hit create button in above screen & then enter first two parameter (Name of new object) following pop-up-

6_1_2_c.png

 

Enhancement Implementation will be created:

6_1_2_d.png

 

Click on highlighted area in screenshot above “Implementing Class”-

  6_1_2_e.png

 

Since we need to apply F4 help restriction on Hierarchy Node variable, we need to select second method in screenshot above (*_NODE).

  1. Code

Following code has been written in that method:

****************Declaration***************************************************************************

  DATA: l_s_node LIKE LINE OF c_t_node,
l_s_hier
LIKE LINE OF c_t_hierarchy.

DATA: lv_curr_user TYPE sy-uname,
lv_date
TYPE sy-datum,
lv_nodeid
TYPE rshienodid,
lv_node
TYPE rsshnodename.

DATA: it_secd TYPE TABLE OF Active Table of BW DSO,
wa_secd
TYPE Active Table of BW DSO.

DATA: it_orgeh TYPE TABLE OF H Table of Orgunit,
wa_orgeh
TYPE H Table of Orgunit,
wa_orgeh1
TYPE H Table of Orgunit.

FIELD-SYMBOLS: <fs_orgeh> TYPE H Table of Orgunit,
<fs_orgeh1>
TYPE H Table of Orgunit.
ASSIGN wa_orgeh TO <fs_orgeh>.
ASSIGN wa_orgeh1 TO <fs_orgeh1>.

*********************************************************************************************************

  IF i_vnam EQ 'V1 <Technical Name of Input Ready Variable'.


CALL FUNCTION 'RSEC_GET_USERNAME'
IMPORTING
e_username
= lv_curr_user.

CLEAR: lv_date.
lv_date
= sy-datum.

SELECT *
FROM Active Table of DSO in BW
INTO TABLE it_secd
WHERE /bic/rmuname = lv_curr_user
AND validfrom LE lv_date
AND validto GE lv_date.

CLEAR wa_secd.

IF it_secd[] IS NOT INITIAL.
SELECT *
FROM H Table of OrgUnit
INTO TABLE it_orgeh
WHERE objvers = 'A'
AND datefrom LE lv_date
AND dateto GE lv_date.

LOOP AT it_secd INTO wa_secd.

CLEAR: l_s_node.
l_s_node
-nodename = wa_secd-orgunit.
******Find if OrgUnit is Leaf Node or not.
READ TABLE it_orgeh ASSIGNING <fs_orgeh>
WITH KEY nodename = l_s_node-nodename.
IF sy-subrc = 0.
CLEAR: lv_nodeid.
lv_nodeid
= <fs_orgeh>-nodeid.
READ TABLE it_orgeh ASSIGNING <fs_orgeh1>
WITH KEY parentid = lv_nodeid.
IF sy-subrc EQ 0. """This will mean, given OrgUnit is not leaf node
l_s_node
-niobjnm = 'ORGUNIT'. ""This is required only if OrgUnit is not Leaf node
"l_s_node-niobjnm = I_IOBJNM.
ENDIF.
ENDIF.

APPEND l_s_node TO c_t_node.

ENDLOOP.

ENDIF.



ENDIF.

*********************************************************************************************************

6.1.3 Expected output of F4 Restriction based on Sample Values

  6_1_3.png

Blue colored OrgUnits are assigned to user in BW DSO. Hierarchy shown on left side is main OrgUnit hierarchy and the one on right side is after applying code.

Using F4 help restriction, user can’t make selection on those strands of hierarchy which doesn’t have any of assigned OrgUnits, but he can still select OrgUnit which is parent of OrgUnit(s) assigned to him. To take care of this scenario, we created customer exit variable (i_step = 2), more details in next section.

 

 

 

6.2 Customer Exit (No Input Ready)

This is non-input ready customer exit variable to be processed in i_step = 2. This variable is used in “Characteristic Restrictions” section of Filter pane.

As discussed in last part of previous section, even after applying F4 help restriction, user can still select OrgUnit which is parent of OrgUnit he is assigned to. These kind of scenarios are handled in this customer exit code. Basically following are two reasons of having this additional variable on OrgUnit:

  1. a)     If user selects nothing in “input ready variable”, then this customer exit will pass all OrgUnits from security DSO in BW in second Variable V2. Which means, user will see data only for the OrgUnits assigned to him.
  2. b)    Validate selection made by user in variable V1. If user has selected something he is not authorized for then pass error.

6.2.1       Code of the Customer Exit (Class à Method)

Code is not written directly in CMOD, but instead using interface class in CMOD, code is written in class specific to the variable V2.

**************************************************************************************

METHOD Interface Class~execute.
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(I_VNAM)          LIKE  RSZGLOBV-VNAM
*"     VALUE(I_VARTYP)        LIKE  RSZGLOBV-VARTYP
*"     VALUE(I_IOBJNM)        LIKE  RSZGLOBV-IOBJNM
*"     VALUE(I_S_COB_PRO)     TYPE  RSD_S_COB_PRO
*"     VALUE(I_S_RKB1D)       TYPE  RSR_S_RKB1D
*"     VALUE(I_PERIV)         TYPE  RRO01_S_RKB1F-PERIV
*"     VALUE(I_T_VAR_RANGE)   TYPE  RRS0_T_VAR_RANGE
*"     VALUE(I_STEP)          TYPE  I DEFAULT 0
*"  EXPORTING
*"     VALUE(E_T_RANGE)       TYPE  RSR_T_RANGESID
*"     VALUE(E_MEEHT)         LIKE  RSZGLOBV-MEEHT
*"     VALUE(E_MEFAC)         LIKE  RSZGLOBV-MEFAC
*"     VALUE(E_WAERS)         LIKE  RSZGLOBV-WAERS
*"     VALUE(E_WHFAC)         LIKE  RSZGLOBV-WHFAC
*"     VALUE(E_VAR_PROCESSED) TYPE  C
*"  CHANGING
*"     VALUE(C_S_CUSTOMER)    TYPE  RRO04_S_CUSTOMER OPTIONAL
*"----------------------------------------------------------------------
*-----------------------------------------------------------------------
* Data Declaration
*-----------------------------------------------------------------------
DATA: l_s_range      TYPE rsr_s_rangesid,
l_s_var_range 
TYPE rrrangeexit.

FIELD-SYMBOLS: <fs_var_range> TYPE rrrangeexit.
ASSIGN l_s_var_range TO <fs_var_range>.

DATA: lv_curr_user TYPE sy-uname,
lv_date
TYPE sy-datum,
lv_nodeid
TYPE rshienodid,
lv_node
TYPE rsshnodename,
lv_level
TYPE rstlevel,
lv_message
TYPE string,
lv_count
TYPE i VALUE 0,
lv_flag
TYPE i VALUE 0,
lv_check
TYPE i VALUE 0.


***** Internal Table for Security DSO
DATA: it_secd TYPE TABLE OF Active table of security DSO,
wa_secd
TYPE Active table of security DSO.

***** Internal Table for Hierarchy Table
DATA: it_orgeh TYPE TABLE OF H Table of OrgUnit,
it_allwd
TYPE TABLE OF H Table of OrgUnit,
wa_orgeh
TYPE H Table of OrgUnit,
wa_orgeh1
TYPE H Table of OrgUnit,
wa_orgeh2
TYPE H Table of OrgUnit,
wa_allwd
TYPE H Table of OrgUnit,
wa_allwd1
TYPE H Table of OrgUnit,
wa_allwd2
TYPE H Table of OrgUnit.

FIELD-SYMBOLS: <fs_orgeh> TYPE H Table of OrgUnit,
<fs_orgeh1>
TYPE H Table of OrgUnit.
ASSIGN wa_orgeh TO <fs_orgeh>.
ASSIGN wa_orgeh1 TO <fs_orgeh1>.

*-----------------------------------------------------------------------
* Constants Declaration
*-----------------------------------------------------------------------
CONSTANTS: c_x TYPE c VALUE 'X'.

*-----------------------------------------------------------------------
* Check the I_STEP = 1,2, or 3
*-----------------------------------------------------------------------

IF i_step = 2.

********Security
CALL FUNCTION 'RSEC_GET_USERNAME'
IMPORTING
e_username
= lv_curr_user.

CLEAR: lv_date.
lv_date
= sy-datum.

SELECT *
FROM Active table of security DSO
INTO TABLE it_secd
WHERE /bic/rmuname = lv_curr_user
AND validfrom LE lv_date
AND validto GE lv_date.

IF it_secd[] IS NOT INITIAL.

CLEAR wa_secd.

SELECT *
FROM H Table of OrgUnit
INTO TABLE it_orgeh
WHERE objvers = 'A'
AND datefrom LE lv_date
AND dateto GE lv_date.

SORT it_orgeh BY nodename.

READ TABLE i_t_var_range INTO l_s_var_range
WITH KEY vnam = 'V1 <Input Ready Variable as mentioned in section 6.1>'.

IF sy-subrc = 0.

lv_count
= 0.

LOOP AT it_secd INTO wa_secd.
CLEAR: lv_node.
lv_node
= wa_secd-OrgUnit.

READ TABLE it_orgeh INTO wa_orgeh
WITH KEY nodename = lv_node.
IF sy-subrc = 0.
APPEND wa_orgeh TO it_allwd.
ENDIF.

ENDLOOP.

SORT it_allwd BY tlevel ASCENDING.

READ TABLE it_allwd INTO wa_allwd INDEX 1. ""Sy-Subrc check not required, as we are reading first record in the table
lv_level
= wa_allwd-tlevel.

CLEAR: lv_nodeid, lv_node.
LOOP AT i_t_var_range INTO l_s_var_range
WHERE vnam = 'V1 <Input Ready Variable as mentioned in section 6.1>'.
CLEAR: l_s_range, lv_nodeid, lv_node.
CLEAR: l_s_range, lv_node.
lv_node
= l_s_var_range-low.
*********Authorization Check*****
CLEAR: wa_orgeh.
READ TABLE it_orgeh INTO wa_orgeh
WITH KEY nodename = lv_node.
IF sy-subrc = 0.
IF wa_orgeh-tlevel < lv_level. ""Check 1

lv_message
= 'Not Authorized for OrgUnit'.
CONCATENATE lv_message l_s_var_range-low INTO lv_message SEPARATED BY space.
**********Information Message 1
CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
EXPORTING
i_class 
= 'RSBBS'
i_type  
= 'A'
i_number
= '000'
i_msgv1 
= lv_message
EXCEPTIONS
dummy   
= 1
OTHERS   = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
CONTINUE. """Skip this Selection as user don't have authorization at this level.
*************************
ELSEIF wa_orgeh-tlevel = lv_level. ""Check 2
READ TABLE it_allwd INTO wa_allwd
WITH KEY nodename = lv_node.
IF sy-subrc NE 0.
""If Record not Found. If level of Selected OrgUnit selected is equal to lowest level of Authorized OrgUnits,
""then Selected OrgUnit should be present in IT_ALLWD. If not then it would mean not autorized.


lv_message
= 'Not Authorized for OrgUnit'.
CONCATENATE lv_message l_s_var_range-low INTO lv_message SEPARATED BY space.
**********Information Message 2
CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
EXPORTING
i_class 
= 'RSBBS'
i_type  
= 'A'
i_number
= '000'
i_msgv1 
= lv_message
EXCEPTIONS
dummy   
= 1
OTHERS   = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
CONTINUE. """Skip this Selection as user don't have authorization at this level.
ENDIF.

ELSE. """if level of Selected OrgUnit is greater than the lowest level of authorized OrgUnits i.e. Selected OrgUnit is in lower or child levels of Authorized OrgUnit.
" BREAK-POINT.

READ TABLE it_allwd INTO wa_allwd
WITH KEY nodename = lv_node.
IF sy-subrc NE 0. ""Record not Found, hence further checks are required
*****************************************
CLEAR: wa_orgeh, wa_orgeh1, wa_allwd1.
READ TABLE it_orgeh INTO wa_orgeh
WITH KEY nodename = lv_node.
IF sy-subrc = 0.
READ TABLE it_orgeh INTO wa_orgeh1
WITH KEY nodeid = wa_orgeh-parentid.
IF sy-subrc = 0.
READ TABLE it_allwd INTO wa_allwd1
WITH KEY nodename = wa_orgeh1-nodename.
IF sy-subrc = 0.
**********************""No Action Required. Selected value will be passed on to e_t_range based on following code
ELSE.
***WHILE*************************
lv_nodeid
= wa_orgeh1-parentid.""Checking Parent OrgUnit
lv_flag
= 0.
WHILE lv_flag = 0.
CLEAR: wa_orgeh2, wa_allwd2.
READ TABLE it_orgeh INTO wa_orgeh2
WITH KEY nodeid = lv_nodeid.""Checking Parent OrgUnit
IF sy-subrc = 0.
READ TABLE it_allwd INTO wa_allwd2
WITH KEY nodename = wa_orgeh2-nodename.
IF sy-subrc = 0.
lv_flag
= 1.
lv_check
= 1. ""Authorization Check Successful
EXIT.
ELSE.
IF wa_orgeh2-tlevel = 2. ""2 is the Lowest Level, level 1 contains ROOT node, which shall not be used in Z table.
lv_flag
= 1.
lv_check
= 0. ""Authorization Check Failed
EXIT.
ENDIF.
lv_nodeid
= wa_orgeh2-parentid.
lv_flag
= 0.

ENDIF.
ELSE.
lv_flag
= 1.
lv_check
= 0. ""Authorization Check Failed
ENDIF.

ENDWHILE.

***ENDWHILE***********************
IF lv_check = 0.""""""" Based on Check Carried out in WHILE.
*********************"""No Authorization for the selected OrgUnit

lv_message
= 'Not Authorized for OrgUnit'.
CONCATENATE lv_message l_s_var_range-low INTO lv_message SEPARATED BY space.
**********Information Message 3
CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
EXPORTING
i_class 
= 'RSBBS'
i_type  
= 'A'
i_number
= '000'
i_msgv1 
= lv_message
EXCEPTIONS
dummy   
= 1
OTHERS   = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
CONTINUE. """Skip this Selection as user don't have authorization at this level.
ENDIF.""""""" Based on Check Carried out in WHILE
ENDIF.
ENDIF.
ENDIF.
*****************************************
ENDIF.

ENDIF.
ENDIF.
********************************
l_s_range
-sign = 'I'.
l_s_range
-opt  = 'EQ'.
l_s_range
-low = l_s_var_range-low.

******Find if OrgUnit is Leaf Node or not.
READ TABLE it_orgeh ASSIGNING <fs_orgeh>
WITH KEY nodename = lv_node.
IF sy-subrc = 0.
CLEAR: lv_nodeid.
lv_nodeid
= <fs_orgeh>-nodeid.
READ TABLE it_orgeh ASSIGNING <fs_orgeh1>
WITH KEY parentid = lv_nodeid.
IF sy-subrc EQ 0. """This will mean, given OrgUnit is not leaf node
""IF wa_secd-OrgUnit = 'ROOT'.
""l_s_range-high = '0HIER_NODE'.
""ELSE.
"BREAK-POINT.
l_s_range
-high = 'ORGUNIT'. ""This is required only if OrgUnit is not Leaf node
""ENDIF.
ENDIF.
ENDIF.

APPEND l_s_range TO e_t_range.

lv_count
= lv_count + 1.

ENDLOOP.

****************************************************************************************************************************
IF lv_count = 0.
********User didn't selected any valid value---using code E1_Part to pass authorized values
*---------COPY_E1_PART--------------------------------------------------------------
*""No Value passed in variable RMCN_ORGUNIT2, hence need to
*""populate it based on authorization
*-----------------------------------------------------------------------
LOOP AT it_secd INTO wa_secd.

CLEAR: l_s_range, lv_node.
l_s_range
-sign = 'I'.
l_s_range
-opt  = 'EQ'.
l_s_range
-low = wa_secd-OrgUnit.
lv_node
= wa_secd-OrgUnit.
******Find if OrgUnit is Leaf Node or not.
READ TABLE it_orgeh ASSIGNING <fs_orgeh>
WITH KEY nodename = lv_node BINARY SEARCH.
IF sy-subrc = 0.
CLEAR: lv_nodeid.
lv_nodeid
= <fs_orgeh>-nodeid.
READ TABLE it_orgeh ASSIGNING <fs_orgeh1>
WITH KEY parentid = lv_nodeid.
IF sy-subrc EQ 0. """This will mean, given OrgUnit is not leaf node
""IF wa_secd-OrgUnit = 'ROOT'.
""l_s_range-high = '0HIER_NODE'.
""ELSE.
"BREAK-POINT.
l_s_range
-high = 'ORGUNIT'. ""This is required only if OrgUnit is not Leaf node
""ENDIF.
ENDIF.
ENDIF.

APPEND l_s_range TO e_t_range.

ENDLOOP.

* Don't remove
e_var_processed
= c_x.
ENDIF.
****************************************************************************************************************************
ELSE.
*---------E1_PART--------------------------------------------------------------
*""No Value passed in variable V1, hence need to
*""populate it based on authorization
*-----------------------------------------------------------------------
LOOP AT it_secd INTO wa_secd.

CLEAR: l_s_range, lv_node.
l_s_range
-sign = 'I'.
l_s_range
-opt  = 'EQ'.
l_s_range
-low = wa_secd-OrgUnit.
lv_node
= wa_secd-OrgUnit.
******Find if OrgUnit is Leaf Node or not.
READ TABLE it_orgeh ASSIGNING <fs_orgeh>
WITH KEY nodename = lv_node BINARY SEARCH.
IF sy-subrc = 0.
CLEAR: lv_nodeid.
lv_nodeid
= <fs_orgeh>-nodeid.
READ TABLE it_orgeh ASSIGNING <fs_orgeh1>
WITH KEY parentid = lv_nodeid.
IF sy-subrc EQ 0. """This will mean, given OrgUnit is not leaf node
""IF wa_secd-OrgUnit = 'ROOT'.
""l_s_range-high = '0HIER_NODE'.
""ELSE.
"BREAK-POINT.
l_s_range
-high = 'ORGUNIT'. ""This is required only if OrgUnit is not Leaf node
""ENDIF.
ENDIF.
ENDIF.

APPEND l_s_range TO e_t_range.

ENDLOOP.

* Don't remove
e_var_processed
= c_x.
ENDIF.

ELSE.

CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
EXPORTING
i_class 
= 'RSBBS'
i_type  
= 'A'
i_number
= '000'
i_msgv1 
= 'No Org Unit assigned for this User'
EXCEPTIONS
dummy   
= 1
OTHERS   = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
ENDIF.

ENDIF.

**************************************************************************************

 

 

7 Conclusion

7.1 Dynamic Security for BW Reporting

  1. a)     Simple roles are required for users restricting them to specific Infoarea, Infoproviders & BEx queries (using Wild Characters).
  2. b)    In security roles need not maintain OrgUnit values, which may change based on employee’s position changes.
  3. c)     If a User is moved in OrgUnit hierarchy in ECC based on HR actions (Promotion or Transfer), this change will come to BW DSO automatically and end users reporting authorizations are automatically taken care of.
  4. d)    If any user needs ad-hoc OrgUnit assignments, just need to maintain Z table with validity dates for ad-hoc assignment and rest all taken care post loading the table in BW.

7.2 Brief of Fucntioning

If user doesn’t enter anything in input ready variable, second customer exit variable will filter report based on OrgUnits assigned to the user.

If user selects something in first input ready variable (where F4 help restriction is applied), second variable will validate security based on OrgUnit assignments.

 

8 References

F4 Help Restriction

http://wiki.scn.sap.com/wiki/display/BI/F4+BADI+RESTRICTION+NODE

http://wiki.scn.sap.com/wiki/display/BI/F4+BADI

http://scn.sap.com/community/data-warehousing/bw/blog/2010/09/30/howto-restrict-f4-help-values-for-hierarchies-in-bex-variable-screen


Viewing all articles
Browse latest Browse all 1574

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>