Skip to Content
Author's profile photo Horst Keller

ABAP News for Release 7.50 – ABAP CDS Access Control

Imagine you have written a nice CDS view, e.g. as follows:

@AbapCatalog.sqlViewName: ‘Z_T100_SABDEMOS’

define view z_t100_sabapdemos

  as select from t100

    { * }  where arbgb = ‘SABAPDEMOS’

It should select all messages for a distinct message class SABAPDEMOS from database table t100. And of course it does that, as the following code snippet proves:

SELECT *

      FROM z_t100_sabapdemos

      INTO TABLE @DATA(result).

cl_demo_output=>display( result ).

/wp-content/uploads/2015/12/access_cntrl1_846142.gif

Now your’re happy and ship your view, but ….

… someday you get an error message from a target system that users do not see all languages any more:

/wp-content/uploads/2015/12/access_cntrl2_846212.gif

… and some users do not see anything at all (sy-subrc = 4).

You logon to the system and examine the database access with SQL Trace (ST05) and find funny things:

/wp-content/uploads/2015/12/access_cntrl3_846213.gif

“DCL restrictions” what’s that now???

You look at the properties of your view in that system and find in the Problems tab:

/wp-content/uploads/2015/12/access_cntrl4_846214.gif

Uh-huh.

  • You’re view implicitly uses the default annotation @AccessControl.authorizationCheck: #CHECK.

    Documentation says “If Open SQL is used to access the view, an access control is carried out implicitly if a CDS role is assigned to the view.

  • And someone has created a CDS role in a DCL source code for your view!

You find it in ADT:

/wp-content/uploads/2015/12/access_cntrl5_846239.gif

@MappingRole: true

define role role_name {

  grant select on z_t100_sabapdemos

  where ( arbgb ) =  aspect pfcg_auth ( s_develop, objname,

                                                  objtype = ‘MSAG’,

                                                  actvt  = ’03’ )

                    and sprsl= ‘E’ ; }

What does that harmless looking code snippet do?

A CDS role adds an additional selection condition, a so called access condition, to a CDS view! If you access a CDS view that is mentioned in a role, Open SQL from ABAP 7.50 (and SADL Queries from ABAP 7.40, SP10) implicitly consider the access conditions defined in each role.

In our case:

  • A literal condition sprsl=’E’ restricts access to English only.
  • A so called PFCG condition aspect pfcg_auth ( s_develop … ) connects the CDS role to a classical authorization object s_develop and from that the CDS access control runtime generates an access condition that evaluates the authorizations of the current user for that object. Here, a predefined aspect pfcg_auth connects the authorization field objname to the view field arbgb. Additionaly, the user’s authorization is checked if it complies with fixed values for authorization fields objtype and actvt.

Neat!

If you write a view, you must be aware that this can happen. If you don’t want any access restriction, you must decorate your view with the annotation AccessControl.authorizationCheck: #NOT_ALLOWED. Then and only then CDS roles are ignored.

But of course, CDS access control becomes part of your data modeling efforts from ABAP 7.50 on  …

For more information, see ABAP CDS – Access Control.

PS: The CDS roles supported by ABAP CDS up to now are implicitly assigned to each user, so to say. User specific CDS roles are principally possible but not supported yet (those would involve selfdefined aspects). Instead, PFCG conditions offer a new implicit access to classical authorizations.

_

Assigned Tags

      17 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Just out of curiosity,
      1. Will we be able to see what access controls are defined for CDS view (e.g. Where-used function or simple navigation from the objects tree)?

      2. Is the authorization check (pfcg_auth) done in DB level or translated to SQL statement before being sent to DB? (And can it be displayed directly in the trace?)

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      1. Up to now only in problems tab. But I guess there will be demand for more.

      2. As far as I know a generated SQL statement is sent by DBI. The actual realization can be seen but is subject to change. It's not necessarily a simple WHERE but also access views can be generated.

      Author's profile photo Former Member
      Former Member

      Thanks.

      1. Sounds like a legitimate request for me.

      2. I would be happy to learn more about the internal mechanism.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      1. Yes

      2. Well, it's internal ...

      Author's profile photo Former Member
      Former Member

      2. Well, I've already said it's just out of curiosity 😉

      (In general, I do like to understand "how things work", even internally).

      Author's profile photo Tracy Xian
      Tracy Xian

      In case a new CDS view needs to be created from existing CDS view(s),  should we provide the access control for the new CDS view?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Yes, if you access a CDS entity in another one no access control is carried out. As a conequence wrapping one view in another one means to circumvent its access controls. You must create a role for the wrapping view too.

      Author's profile photo Mohit Chopra
      Mohit Chopra

      Hello Horst,

      I have couple of doubts regarding DCL roles.

      1. I created a DCL role as displayed below.

      @EndUserText.label: 'role_label'

      @MappingRole: true

      define role zscarr_role {

          grant select on Zscarr

          where ( CARRID ) =

          aspect pfcg_auth (  Z_CDS_MC,

                              carrid,

                              actvt = '03' );

      }

      Its working perfectly fine. In Authorization Object Z_CDS_MC i have Actvt 1 , 2 and 3 checked. What i analyzed is that it does not really matter what actvt i give in DCL Role. For Ex. I gave actvt ='03' in above Role but it always goes and check What activities are permitted in authorization Object. Just needed to understand why is actvt added as a part of above syntax??

      2. The above role Only works if i try to access data from CDS Entity in Open SQL which is correct as well because all semantics are attached with CDS entity. Just needed to understand if in HANA Database level someone tries to access CDS SQL View which got generated automatically for CDS entity than how will authorization work? Do we need to provide separate authorization at HANA Level where we can only access CDS SQL View?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hi Mohit,

      1) I guess it works as documented. You say, you have all Actvts checked in the authorization object. The documentation says

      • Further optional authorization fields auth_field1,auth_field2 of the authorization object can be specified to which literal values can be mapped using =. In this case, the evaluation only respects those authorizations of the current user in which all values specified in this way exist. Here, the same authorization field can be specified more than once with different values.

      It is merely a filter, which authorizations to check. If you specify actvt = '03'  (or another) those authorizations are checked, where these value are covered. See also the second bullet point in the example of the documentation.

      2) For that the documentation says

      f a CDS role is defined for a CDS entity, the access conditions are evaluated implicitly each time an object is accessed using Open SQL or using an SADL query ...

      and further

      When CDS views used as data sources in different CDS entities are accessed indirectly, no implicit access control takes place. This means the methods and CDS roles used to access CDS entities should be planned carefully when modeling an application. For example, accesses made on CDS entities without associated CDS role can be wrapped in CDS views with associated roles.

      Of course, when you access the physical DB view with Native SQL, the DCL role is not considered at all.

      Author's profile photo Mohit Chopra
      Mohit Chopra

      Thank You very much Horst... 🙂

      Author's profile photo Hans Bellens
      Hans Bellens

      Hi Horst,

      Any chance that the implicit auth-check (now to be done via the define role and grant in the DCL statement) will become available as an 'ABAP CDS - Special Functions' in the DDL statement ?

      Now, if someone uses 'select * from cds_name' the results will be different when compared to 'select * from sqlviewname'.

      I was thinking of doing somehting like this: using the aspect pfcg_auth as a where clause (see below, I know ... syntax is not supported). This way the implicit auth-check would become available to the sqlViewName as well, and checked e.g. when using the sqlViewName in SE16N.

      Below my dummy code for creating a view on VBAK, limited to the user's allowed VKORGs, and both names (z_cds_vbak_auth and z_v_vbak_auth) would use the implicit auth-check

      @AbapCatalog.sqlViewName: 'z_v_vbak_auth'
      @AbapCatalog.compiler.compareFilter: true
      @AccessControl.authorizationCheck: #CHECK
      @EndUserText.label: 'VBAK with implicit authorization'

      define view z_cds_vbak_auth
      as select from vbak { * }
      where vkorg in pfcg_auth( 'V_VBRK_VKO', vkorg, actvt = '03' )

      To me this seems a little bit similar as the use of Methods add_authorization_object and get_sql_condition from Class cl_auth_objects_to_sql which allow to follow the Code Pushdown paradigm.

      Or would the possible use of pfcg_auth in the DDL statement cause huge performance problems?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      "Now, if someone uses ‘select * from cds_name’ the results will be different when compared to ‘select * from sqlviewname’."

      Yes, and because of this and other reasons, the access to an CDS view's database view, which is there for technical reasons, is declared as

      obsolete .

      There won't be any support for it.

       

      Author's profile photo Hans Bellens
      Hans Bellens

      Thanks for your reply!

      Author's profile photo Iwan Santoso
      Iwan Santoso

      Hi Horst,

      In some SAP standard CDS view, we have access control annotation set as #NOT_ALLOWED for example C_ProfitAndLossQ2901.

      @AbapCatalog.sqlViewName: 'CFIPROFLOSSQ2901'
      @EndUserText.label: 'P&L - Actuals'
      @VDM.viewType: #CONSUMPTION
      @Analytics.query: true
      @AccessControl.authorizationCheck: #NOT_ALLOWED
      define view C_ProfitAndLossQ2901
      with parameters

      What options is available if we want to restrict user only to be able to see specific company code data. So far, we changed the DDL annotation, but if there is upgrade or Service pack that update the same CDS view, our changes will be overwritten. Do we have modification free option on this?

       

      Regards,

      Iwan

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

       

      Nothing that I know of. Metadata Extensions do not work for AccessControl.authorizationCheck. EXTEND VIEW also doesn't help.

      More a question to the owners of the views, why they have annotated their views in such a way and what they think about your customer scenario.

      Author's profile photo Iwan Santoso
      Iwan Santoso

      Danke Horst.

       

      I'll open incident ticket to get some direction from the owners of the view and letting them know out scenarios.

       

      Regards,

      Iwan

      Author's profile photo Konstantin Klein
      Konstantin Klein

      Do you know if it's possible to access ABAP constants from within the Access Control Definition? There are quite a few cases where ABAP classes do have constant attributes named `co_auth_...`  carrying e.g. the value '03'. This would lead to code that is both more readable and maintainable:

      @MappingRole: true
      define role role_name {
        grant select on z_t100_sabapdemos
        where ( arbgb ) =  aspect pfcg_auth ( s_develop, objname,
                                              objtype = ‘MSAG’,
                                              actvt  = @cl_some_class=>co_auth_do_something_meaningful )
        and sprsl= ‘E’ ; 
      }