本文阅读目录
- 计算机软件权限控制模块的基本概念
- ABAP 权限控制设计的三大实体
- 具体实操:创建 Authorization Object
- 具体实操:创建用户 Role
- 具体实操:使用 AUTHORITY-CHECK 进行权限检查
笔者的知识星球里,一个朋友问我有没有关于 ABAP 权限控制入门级的介绍文章。
本公众号之前没有写过类似主题的文章,本文就来聊聊一些关于 ABAP 权限控制入门级的知识。
计算机软件的权限控制,包含 Authentication 和 Authorization 两个层面的内容。
- 身份验证(Authentication):身份验证是权限控制的第一步,用于确认用户的身份。系统通过验证用户提供的凭据(如用户名和密码、数字证书或者生物特征等)来确定用户是谁。
- 授权(Authorization):授权是指在身份验证通过后,系统决定该用户是否有权执行特定操作或访问特定资源。这部分涉及定义和管理访问控制(Access Control)规则和策略。
本文介绍的是 Authorization 层面的内容。
权限控制模块对于任何行业的软件,其重要性都不言而喻。它不仅仅是一个确保系统安全的工具,更是维护整个软件系统正常运行、保护用户数据隐私、保证业务流程顺利进行的核心组成部分。
权限控制模块通过严格的身份验证、授权机制以及访问控制策略,确保只有经过授权的用户才能执行特定操作,访问特定资源。
为了在权限控制管理粒度,灵活性,可扩展性和实施复杂度等几个因素之间实现最佳平衡,ABAP 引入了角色(Role)的概念。
角色管理是 ABAP 系统权限控制模块的重要部分。通过为用户分配不同的角色,系统可以更灵活地管理和控制权限。一个角色可以是一个预定义的权限集合,用户可以根据其角色获取相应的权限,即所谓的 RBAM 思路 - Role Based Authorization Management.
这些概念有不少都是触类旁通的,比如 SAP BTP 里,系统管理员同样需要根据实际业务需要,把角色分配给对应的用户,如下图所示:
ABAP 权限控制设计的三大实体
笔者认为对于 ABAP 权限控制的初学者,搞清楚 ABAP Role 和 Authorization Object, 以及 ABAP 关键字 AUTHORITY-CHECK 这三个概念就可以了。
用户使用某应用,查询业务数据。该应用通过 ABAP AUTHORITY-CHECK 关键字,查询该用户是否被分配了完成该业务操作所必须的权限。
ABAP 进行权限检查的关键字 AUTHORITY-CHECK,检查的对象是 Authorization Object,该对象不会直接分配给用户,而是通过 Role 这个载体来完成。
换言之,Authorization Object 分配给 Role,Role 再分配给用户。这种关系如下图所示,图片来自博客:https://sap-authorization-universe.com/2021/03/13/basics-abap...
我们动手开发一个支持权限控制的 ABAP 应用程序之前,首先要想清楚:该应用支持哪些业务操作?
比如一个产品管理应用里,有一个业务操作:对笔记本类别的产品,进行查看和修改。
又比如一个航班信息应用里,有一个业务操作:对航空公司 ID 为 CA 即国航的所有航班信息,进行查看。
那么这些业务操作,就可以抽象成为一个个 Authorization Object.
Authorization Object 的字段类型有两种,一种是包含业务信息的字段,可以理解成英文单词里的名词,比如上面例子里的产品类别,和航空公司的编码号。
另一种类型是允许的操作,可以理解成动词,比如 SAP 约定俗成的惯例,01 代表创建,02 代表修改,03 代表查看。
我们根据这些业务需求,创建好 Authorization Object 之后,再继续创建 Role ,然后将 Authorization Object 分配到 Role 中。
如果想允许某个用户有权限进行这些业务操作,只需要将创建好的 Role,分配给这些用户即可。
当然,在应用的 ABAP 源代码里,我们要使用 AUTHORITY-CHECK 关键字,进行对应的权限检查。
以上的步骤听起来可能有些抽象,我们通过一个简单的例子来动手实操。
基于 SAP 著名的航班模型,假设我想开发一个 ABAP 报表,只有具备相应权限的用户,才能使用此报表查看航空公司 SQ 旗下的航班信息。
1. 创建 Authorization Object
我们使用事务码 SU21,能看到 SAP 发布的标准 Authorization Object 列表。每个 Authorization Object 都放到一个 Authorization Class 里,二者的关系可以类比成文件系统里的文件和文件夹。
新建一个 Authorization Class,取名 ZCDS.
接下来创建 Authorization Object,下图是我创建好的授权对象,名称为 ZSPFLI_AUT,包含两个 Authorization Fields.
前文已经阐述过,这两个字段,分别描述业务操作要查看的「业务数据」,以及针对这些数据,进行的「业务操作类型」。
每个 Authorization Field 必须分配对应的 Data Element.
第一个 Authorization Field,ZSPFLI_CTR 是我在 SU21 事务码的 Authorization Object 创建页面里新建的字段,Data Element 使用数据库表 SPFLI 的 CARRID 字段的 Data Element 即可。
另一个 ACTVT 字段,我选择了重用系统里的标准字段,描述对航班信息的业务操作类型,值指定为 03 即查看操作。
2. 创建 Role
使用事务码 PFCG 创建一个新的 Role:
将前一步骤创建的 Authorization Object 手动分配给该 Role(图例1),Authorization Object 的两个字段值,分别维护成 03 - Display(图例2)和某航空公司的 ID 值 SQ(图例3),最后点击 Generate(图例4)按钮,让这些修改在整个系统生效。
这一步操作之后,我们得到了一个新的 Role ZSPFLI_ROLE.
将某用户分配给这个 Role 的业务含义,就是允许该用户具有查询航空公司 SQ 的航班信息的权限。
完成这一步之后,我们点击 User 面板,就可以将指定用户,分配给这个 Role 了,如下图所示。
现在我先不急着将自己的用户分配给这个 Role,因为我想展示 ABAP 程序里,权限检测失败的情形。
3. 使用 AUTHORITY-CHECK 进行权限检查
使用如下的 ABAP 代码进行权限检查:
DATA: lv_carrid TYPE spfli-carrid VALUE 'SQ'.
AUTHORITY-CHECK OBJECT 'ZSPFLI_AUT' ID 'ZSPFLI_CTR' FIELD lv_carrid
ID 'ACTVT' FIELD '03'.
WRITE:/ sy-subrc.
可以看出,传递给 AUTHORITY-CHECK 关键字的输入值是 Authorization Object 的名称和两个 Authorization Field 的值。
上述代码的语义,翻译成自然语言就是,检查当前登录用户,是否具有「查看」(因为 03 代表 Display)航空公司 SQ 的航班信息的权限。
因为目前我根本没有给自己的用户分配对应的 Role,所以根据 ABAP 帮助文档的规定,sy-subrc 返回值为 12.
下面我将自己的用户分配给 Role,点击保存。
然后重新运行报表,这一次返回值变成 0,说明权限检查通过。
如果我将 ABAP 代码里航空公司的编号更改成 SQ 之外的其他值,权限检查也会失败,但是返回值变成 4.
这是因为我创建的 Role 里,Authorization Field 的值只指定为 SQ, 所以只能查看该航空公司的航班信息。如果在 Role 里将 SQ 更改成 *, 语义就变为允许查看所有航空公司的航班信息。
ABAP 文档里对 AUTHORITY-CHECK 不同返回值的说明:
我们在 ABAP 报表里,根据 sy-subrc 的不同返回值,来编写对应的逻辑。
- 如果 sy-subrc = 0, 说明权限检查成功,使用 OPEN SQL 从 SPFLI 读取 carrid 为 SQ 的数据
- 如果 sy-subrc = 4 或者 12, 抛出缺少权限的错误信息。
有朋友可能会有这样的疑问:既然是通过 sy-subrc 的返回值来决定下一步的执行逻辑,那就算我没有权限,在 ABAP 调试器里,将变量 sy-subrc 的值,强行修改成 0,不是就可以绕过权限检查了吗?
首先,要想在 ABAP 调试器里修改变量的值,用户 Role 必须包含名叫 S_DEVELOP 的Authorization Object,并且 OBJTYPE 的值必须为 DEBUG 或者 *, ACTVT 的值必须为 02 - Change.
在 SAP 测试和生产系统里,这种配置是不可能的。
其次,笔者之前的文章有了 Debug 权限就能干坏事?小心了,你的一举一动尽在系统监控中提过,就算在开发系统,在调试器里修改变量的值,也会被系统日志记录下来。
所以不推荐用单步调试的方法在开发系统里去绕过权限检查,一是这 有可能引起系统数据和状态不一致,二是如果造成不好的后果,系统管理员通过日志,也能很容易追责。
希望本文的例子,能帮助 ABAP 权限控制的初学者,对这一块领域有最基础的了解,感谢阅读。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。