Preventing Unauthorized Access to Data

Objectives

After completing this lesson, you will be able to:

  • Create authorization fields and authorization objects
  • Implement CDS access controls

Authorization Objects and Authorization Fields

When you develop a data model, you should also think about how to protect the data against unauthorized access. Earlier in this learning journey, you learned that authorization objects form the basis for user specific, role-based authorization control. To protect your data against unauthorized write access, authorization checks are implemented in the ABAP code using keyword AUTHORITY-CHECK. To prevent unauthorized read access, the use of CDS access controls should be the first choice.

An authorization object groups up to ten authorization fields that are related and should be checked together. Authorization fields are separate development objects. The same authorization field can be referenced by more than one authorization object.

Authorization fields are typed with data elements. The data elements, or the domains they use, usually provide the connection between the authorization fields and the data they protect.

Whether your data model requires its own authorization object(s) or whether you use existing ones, strongly depends on how independent your data model is from existing data.

If your data is connected to existing data models, it is always worth searching for existing authorization objects.

Hint

Start the search using the where-used list for the data elements you use in your database tables to see if there are related authorization fields.

Usually, before you create a new authorization object, you create one or more new authorization fields, first.

The authorization field name is limited to 10 characters.

Note that you have to specify an existing data element right from the start. In this example, authorization field Z00DEPMENT is created using data element Z00_DEPARTMENT_ID.

In the maintenance dialog for the authorization field, it is recommended that you specify a Check Table. The check table is a database table that contains the values that are allowed for the authorization field. Depending on your data model, this will be a customizing table or a table with master data. In the example, we use the master data table for departments.

For a newly created authorization field, a warning in the header or on the problems view tells you that the authorization field is not yet used. Links in the What's next? section serve as quick fixes for this warning. Here, you can add the authorization field to an existing authorization object, or create a new authorization object for it.

When you create a new authorization object, you have to provide a name and a description as usual. This name is also limited to 10 characters.

Note

The Object Class defines groups of authorization objects. Whether you can assign an object class or not, depends on the platform on which you develop. On SAP BTP, ABAP Environment, there is currently only one Object Class (CPAE) for all authorization objects.

Any new authorization object contains authorization field ACTVT by default. This field is used to distinguish between various data operations with standardized values.

By default, the authorization object considers activities Create (value "01"), Read (value "03", Update (value "02"), and Delete (value "06"). You can remove activities you do not need, and add more from a large pool of available activities. Place the cursor in the input field and press Ctrl + Space to display the list of available activities.

Note

In rare situations you can even completely remove authorization field ACVT. This should only be done if the authorization check is independent from the performed operation.

To add more authorization fields, place the cursor in the input field and press Ctrl + Space to display the list of available authorization fields.

Hint

Neither authorization fields nor authorization objects have to be activated. It is sufficient to save them.

How to Create an Authorization Object

Play the video to see how to create an authorization object.

Repository Object CDS Access Control

Earlier in this learning journey, you learned that CDS access controls are used to filter data sets based on authorizations. Let us recap the basic principle:

A repository object of type CDS access control defines a CDS role using keyword DEFINE ROLE. Within the role, keyword GRANT SELECT ON relates the CDS role to a CDS entity - for example, a CDS view, and after keyword WHERE, it defines one or more access conditions. Whenever ABAP code accesses the CDS entity, the database interface filters the selection result according to these access conditions.

CDS access controls only have an effect when the CDS entity is accessed from ABAP code directly. They are ignored if the CDS entity is accessed indirectly, for example, through another CDS entity.

Let us look at this example: CDS access control R_EMPLOYEE contains the definition of CDS role R_Employee. It restricts access to the CDS view entity, R_Employee, with an access condition based on user authorizations (PFCG condition).

Access Conditions

CDS access controls support various types of access conditions. The most important access conditions are as follows:

Literal Conditions

A literal condition - also known as a simple condition - compares an element of a CDS entity with a fixed value. Literal conditions are the simplest form of access conditions. They do not depend on the current user. As a result of that, they are usually combined with other types of access conditions.

PFCG Conditions

A PFCG condition - also known as a PFCG Aspect - associates elements of a CDS entity with authorizations in the SAP authorization concept (which are based on authorization objects). PFCG conditions are the most common access condition for CDS entities that read directly from database tables.

Inheritance Conditions

An inheritance condition applies the conditions from another CDS role. Inheritance conditions are the usual access condition for CDS views that read from other CDS entities (View on View).

Let us have a look at some examples for simple conditions.

The first example is a literal condition. It specifies that the value of view element DepartmentId has to equal 'ADMIN' or, in other words, that a read access to the related CDS entity only returns data sets that belong to department ADMIN.

The second example is also a simple access condition, but not a literal. The access condition links view element CreatedBy to the user name of the current user. A read access to the related CDS entity only returns data sets the current user created himself.

The third example illustrates that you can use logical operators AND and OR to combine different access conditions. Here, the conditions are connected with OR, meaning that users can see all data sets they created themselves, no matter the department to which they belong. From the data sets that were created by other users, they can only see those that belong to the department ADMIN.

Hint

When you create a CDS access control based on template Define Role With Simple Condition, you get the basic structure for one literal condition and one user aspect condition.

Examples: PFCG Conditions

CDS roles with only simple access conditions are not very common. If used at all, simple conditions are combined with other access conditions - for example, PFCG conditions. PFCG conditions link one or more view elements to the authorizations in the master data of the current user.

Play the video to see an example of a CDS role with PFCG conditions and Inheritance Conditions.

CDS Access Control Creation

To create a new CDS access control, proceed as follows:

  1. In the Project Explorer, locate the data definition that contains the definition of the CDS entity for which you want to provide access rules.
  2. Right click the data definition and choose New Access Control.
  3. As you create the access control for a specific CDS entity, the Protected Entity input field already contains the name of this CDS entity. Enter a name and a description for the new access control and choose Next.

    Note

    It is strongly recommended that the access control and the protected entity have the same name.

  4. Depending on the required type of access condition, select one of the templates starting with Define Role. Then choose Finish.

Annotation AccessControl.checkAuthorization

When you create a CDS view entity, you can use the @AccessControl.authorization annotation to control whether an access control, can, should, must, or must not exist for this view.

Possible values are as follows:

#NOT_REQUIRED

If a CDS role protects the view, it is evaluated at runtime. The syntax check does not check whether a CDS role exists or not. This is the default value.

#CHECK

Like #NOT_REQUIRED, but with a syntax check warning if no CDS role protects the view.

#MANDATORY

Like #CHECK, but in addition, the system raises a runtime error if no CDS role protects the view.

#NOT_ALLOWED

No access control is performed. If a role is assigned to this view, a syntax warning occurs and the access control is ignored at runtime.

#PRIVILEGED_ONLY

The CDS entity should be accessed using the ABAP SQL addition WITH PRIVILEGED ACCESS. For detailed information, see SAP note: 2725274.

How to Implement a CDS Access Control

Play the video to see how to implement a CDS access control.

Create an Authorization Object and CDS Access Controls

You developed a data model with database tables and CDS view entities. To protect the data against unauthorized access, you define an authorization field and an authorization object. Then you create CDS access controls for your CDS view entities.

Template:

  • n.a.

Solution:

  • /LRN/DPMNT (Authorization Field)
  • /LRN/DPMNT (Authorization Object)
  • /LRN/R_DEPARTMENT_AUT (Access Control)
  • /LRN/R_EMPLOYEE_AUT (Access Control)
  • /LRN/C_DEPARTMENT_AUT (Access Control)
  • /LRN/C_EMPLOYEE_AUT (Access Control)

Prerequisites

For this exercise, you need the CDS view entities which you have created in previous exercises (suggested names were: Z##_R_Department, Z##_R_Employee, Z##_C_DepartmentQuery, and Z##_C_EmployeeQuery, where ## is your group number). If you have not finished those exercises, create copies of the four data definitions from package /LRN/S4D430_EXERCISE, that are ending with _AUT.

Task 1: Define Authorization Object

Define an authorization object to control access to the employee and department data based on the related department (suggested name: Z##DPMENT, where ## is your group number). Define the authorization object with two authorization fields: a new authorization field (suggested name: Z##DPMNT) that is based on your data element for the department ID (suggested name was: Z##_DEPARTMENT_ID), and the standard authorization field ACTVT with the default permitted activities.

Note

If you have not created a data element for the department ID, use the /LRN/DEPARTMENT_ID data element, instead.

Steps

  1. Create an authorization field based on the data element for the department ID (suggested name: Z##DEPMENT).

    1. In the Project Explorer, right-click your package to open the context menu and choose New → Other ABAP Repository Object.

    2. In the filter field, enter au and choose Authorization Field from the suggestion list.

    3. Enter Z##DPMNT as Name and Z##_DEPARTMENT_ID as Data Element. Then choose Next.

    4. Confirm the transport request and choose Finish.

  2. Set your database table for department data as check table (suggested name was: Z##DEPMENT) and save the authorization field.

    Note

    If your authorization field is based on the /LRN/DEPARTMENT_ID data element, you have to use the database table /LRN/DEPMENT_REL.
    1. Place the cursor in theCheck Table field, enter Z## and press Ctrl + Space to open a value help.

    2. From the value help, choose Z##DEPMENT.

    3. Press Ctrl + S to save the authorization field.

  3. Create a new authorization object and assign the authorization field to it.

    1. In the definition of the authorization field, scroll down to the What's next? section and choose Create a new Authorization Object and assign the Authorization Field to it.

    2. Enter Z##DPMNT as Name and Authorization per department as Description, then choose Next.

    3. Confirm the transport request and choose Finish.

  4. Confirm that the new authorization object contains the standard authorization field ACTVT and the default permitted activities.

    1. Inspect the Authorization Fields section which should contain your own authorization field and the default authorization field ACTVT.

    2. Inspect the Permitted Activities section which should contain the four default activities.

  5. Save the authorization object.

    1. Press Ctrl + S to save the authorization object.

Task 2: Define Access Controls

Define access controls for your base view entities, that is, the base view entity for department data (suggested name was: Z##_R_Department) and the base view entity for employee data (suggested name was: Z##_R_Employee). Use a template that allows you to control the access based on the authorization object you just created.

Note

Following a general recommendation, name the access controls after the view entity they protect.

Steps

  1. Open your base view entity for department data in the Data Preview tool.

    1. Open the definition of the view entity and press F8 to open the Data Preview tool.

  2. For this view entity create a CDS access control that defines a CDS role with a PFCG condition.

    1. In the Project Explorer, locate your CDS data definition Z##_R_DEPARTMENT.

    2. Right-click the data definition to open the context menu and choose New Access Control.

    3. Copy the name from the Protected Entity field to the Name field.

    4. In the Description field, enter Department (Access Control), then choose Next.

    5. Confirm the transport request and choose Next.

    6. From the list of Templates, choose Define Role with PFCG Aspect, and choose Finish.

  3. In the generated code, reference your authorization object.

    1. Adjust the code as follows:

      Code Snippet
      12345678910111213
      define role Z##_R_DEPARTMENT { grant select on Z##_R_Department where (entity_element_1, entity_element_2) = aspect pfcg_auth( Z##DPMNT, authorization_field_1, authorization_field_2, filter_field_1 = 'filter_value_1' ); }

      Note

      We introduced additional line-breaks to increase readability in printed training material.
  4. Replace the first placeholder for authorization fields with the name of your authorization field. Then remove the second placeholder.

    1. Adjust the code as follows:

      Code Snippet
      123456789101112
      define role Z##_R_DEPARTMENT { grant select on Z##_R_Department where (entity_element_1, entity_element_2) = aspect pfcg_auth( Z##DPMNT, Z##DPMNT, filter_field_1 = 'filter_value_1' ); }
  5. Use the ACTVT authorization field as a filter field and supply it with the filter value for activity Display.

    1. Adjust the code as follows:

      Code Snippet
      123456789101112
      define role Z##_R_DEPARTMENT { grant select on Z##_R_Department where (entity_element_1, entity_element_2) = aspect pfcg_auth( Z##DPMNT, Z##DPMNT, ACTVT = '03' ); }
  6. Reference a suitable entity element to supply the first authorization field. Then remove the placeholder for a second view element.

    1. Adjust the code as follows:

      Code Snippet
      123456789101112
      define role Z##_R_DEPARTMENT { grant select on Z##_R_Department where ( Id ) = aspect pfcg_auth( Z##DPMNT, Z##DPMNT, ACTVT = '03' ); }
  7. Activate the access control and refresh the display in the Data Preview tool.

    1. Press Ctrl + F3 to activate the development object.

    2. Return to the Data Preview for the protected entity and choose Refresh.

    3. Alternatively, you can press F5 to refresh the displayed data.

  8. To see at least some data, edit the CDS access control again and replace your own authorization object Z##DPMNT with the solution object /LRN/DPMNT and your own authorization field Z##DPMNT with the authorization field /LRN/DPMNT. For this authorization object your user already has some authorizations.

    1. Return to the source code of your CDS access control.

    2. Adjust the code as follows:

      Code Snippet
      123456789101112
      define role Z##_R_DEPARTMENT { grant select on Z##_R_Department where ( Id ) = aspect pfcg_auth( /LRN/DPMNT, /LRN/DPMNT, ACTVT = '03' ); }
    3. Activate the access control and refresh the display in the Data Preview tool.

  9. In the same way, create a CDS access control for your base view entity for employee data.

    1. In the project explorer, locate your CDS data definition Z##_R_EMPLOYEE.

    2. Right-click the data definition to open the context menu and choose New Access Control.

    3. Copy the name from the Protected Entity field to the Name field.

    4. In the Description field, enter Employee (Access Control), then choose Next.

    5. Confirm the transport request and choose Next.

    6. From the list of Templates, choose Define Role with PFCG Aspect, and choose Finish.

    7. Adjust the generated code as follows:

      Code Snippet
      123456789101112
      define role Z##_R_EMPLOYEE { grant select on Z##_R_Employee where ( DepartmentId ) = aspect pfcg_auth( /LRN/DPMNT, /LRN/DPMNT, ACTVT = '03' ); }
  10. Activate the access control.

    1. Press Ctrl + F3 to activate the development object.

Task 3: Define Inheriting Access Controls

Define an access control for the view entity with which you query employee data based on two input parameters (suggested name was: Z##_C_EmployeeQueryP). In the same way, define an access control for your view entity with which you query and employee data per department (suggested name was: Z##_C_DepartmentQuery). In both cases, use a template that allows you to inherit the authorization rules from the underlying view entities.

Note

Following a general recommendation, name the access controls after the view entity they protect.

Steps

  1. Open the definition of your CDS view entity that queries employee data based on two input parameters.

    1. Press Ctrl + Shift + A.

    2. Enter the name of the CDS data definition that you want to open, that is Z##_C_EMPLOYEEQUERYP, and choose OK.

  2. For the view entity with parameters, create a CDS access control that defines a CDS role with inherited conditions.

    1. In the Project Explorer, locate your CDS data definition Z##_C_EMPLOYEEQUERYP.

    2. Right-click the data definition to open the context menu and choose New Access Control.

    3. Copy the name from the Protected Entity field to the Name field.

    4. In the Description field, enter Employee Query (Access Control), then choose Next.

    5. Confirm the transport request and choose Next.

    6. From the list of Templates, choose Define Role with Inherited Conditions, and choose Finish.

  3. In the generated code, reference the view entity the protected entity uses as data source, that is, Z##_R_Employee.

    1. Adjust the code as follows:

      Code Snippet
      1234567
      define role Z##_C_EMPLOYEEQUERYP { grant select on Z##_C_EmployeeQueryP where inheriting conditions from entity Z##_R_Employee; }
  4. Activate the access control.

    1. Press Ctrl + F3 to activate the development object.

  5. Open the definition of your CDS view entity that aggregates employee data per department.

    1. Press Ctrl + Shift + A.

    2. Enter the name of the CDS data definition that you want to open, that is Z##_C_DEPARTMENTQUERY, and choose OK.

  6. Define an access control that inherits the access conditions from the primary data source.

    1. In the Project Explorer, locate your CDS data definition Z##_C_DEPARTMENTQUERY.

    2. Right-click the data definition to open the context menu and choose New Access Control.

    3. Copy the name from the Protected Entity field to the Name field.

    4. In the Description field, enter Department Query (Access Control), then choose Next.

    5. Confirm the transport request and choose Next.

    6. From the list of Templates, choose Define Role with Inherited Conditions, and choose Finish.

    7. Adjust the generated code as follows:

      Code Snippet
      1234567
      define role Z##_C_DEPARTMENTQUERY { grant select on Z##_C_DepartmentQuery where inheriting conditions from entity Z##_R_Department; }
  7. Activate the access control.

    1. Press Ctrl + F3 to activate the development object.

Log in to track your progress & complete quizzes