11 使用用户与角色控制访问#

应用的访问控制不只是在菜单上隐藏几个入口。完整的安全设计需要先确认用户是谁,再判断这个用户能访问哪些页面、数据和操作。APEX 使用认证方案(Authentication Scheme)处理登录;使用角色(Roles)和角色分配(Role Assignments)表达用户在组织中的职责;再通过授权方案(Authorization Scheme)把这些职责转化为可执行的访问规则。

本章示例围绕 Woods HR 应用展开。该应用基于 EBA_DEMO_EMP 以及常见 EMP 表的副本,并补充了一些员工数据。最终目标是让普通员工、HR 代表、应用管理员和经理看到与其职责匹配的页面、列、按钮和数据行。

图 11-1 根据用户职能角色交付差异化体验。

11.1 要求页面经过身份验证#

页面级的 Authentication 属性决定用户是否必须登录才能查看页面。Login Page 这类入口页通常设置为 Page Is Public;大多数业务页面应设置为 Page Requires Authentication,让 APEX 在进入页面前先完成登录检查。

  1. 在 Page Designer 中打开目标页面,例如 Woods HR 的登录页 9999。
  2. 在组件树中选中页面根节点。
  3. 在 Property Editor 中找到 Authentication 属性。
  4. 根据页面用途选择 Page Is PublicPage Requires Authentication

验证点:公开页面应可直接访问;需要认证的页面应先跳转到登录流程,登录后再继续访问。

图 11-2 判断页面是公开访问还是要求登录。

11.2 使用 APEX Accounts 身份验证#

应用的 Authentication Scheme 控制用户如何登录。新建应用默认使用 Oracle APEX Accounts,这意味着登录用户来自当前工作区中维护的 APEX 用户账户。

图 11-3 Oracle APEX Accounts 提供默认认证方案。

工作区管理员可以通过页面右上角的用户与扳手按钮进入 Manage Users and Groups。在账户列表中,管理员会为每个用户设置账户类型:例如 ADINA 是 Workspace Administrator,LEO 和 LUCY 是 Developer,其余用户只作为应用最终用户登录运行时应用。

图 11-4 工作区管理员管理 APEX 用户账户。
图 11-5 从账户列表页面管理用户。

验证点:拥有 Builder 权限的用户可以登录 App Builder;仅为最终用户的账户只能登录你开发的 APEX 应用。

11.3 分配用户角色#

角色用于表达用户在业务中的职责。进入 Shared Components > Application Access Control 后,可以定义应用角色并把用户分配到一个或多个角色。Woods HR 中所有用户都拥有 Employee 角色;ADINA 额外拥有 App Admin;SUSAN 额外拥有 HR Rep

关键差异:角色定义属于应用定义的一部分,会随应用导出和导入;具体用户的角色分配不会随应用新版导入而覆盖目标环境。这样可以保护测试、生产等环境中已有的本地用户授权。

图 11-6 配置角色和角色分配。

验证点:检查 ADINA、SUSAN 和普通员工登录后的功能差异是否与角色分配一致。

11.4 使用规则和角色塑造用户体验#

Authorization Scheme 是可以挂到应用元素上的访问规则。它不局限于页面,也可以用于导航菜单、报表列、页面项、按钮、编辑链接和页面流程。配置后,APEX 会根据当前用户的角色或自定义逻辑自动调整最终用户体验。

本节示例把授权方案应用到 Woods HR 的菜单、页面、列、按钮和编辑入口,目标是让用户只能看到并执行自己职责允许的操作。

11.4.1 声明授权方案规则#

授权方案应按它执行的规则命名。Woods HR 定义了三个基于角色成员身份的规则:

  • Administrators Only:只授权应用管理员。
  • Any Employee:授权所有员工。
  • HR Representatives Only:只授权 HR 代表。

这三个规则都使用内置 Scheme Type Is In Role or Group。Administrators Only 使用 Application Role 检查类型,并指定角色名 App Admin。由于管理功能敏感,它设置为 Once per page view;其他两个规则可设置为 Once per session,以减少重复计算。

图 11-7 使用角色成员身份配置授权方案规则。
图 11-8 基于角色成员身份的授权方案详情。

注意:Name(s) 字段可以填写逗号分隔的多个角色名;用户属于其中任意一个角色即可通过授权。

11.4.2 授权菜单访问#

Navigation Menu 列表决定用户能点击哪些业务入口。默认情况下,菜单项对所有用户可见,包括未登录用户。Woods HR 对菜单项配置不同授权方案:

  • Home:使用 Must Not Be Public User,用户必须已登录。
  • Employee Directory:使用 Any Employee,任何员工可访问。
  • Salary Review:使用 HR Representative Only,只有 HR 代表可访问。
  • Administration:使用 Administrators Only,只有应用管理员可访问。
图 11-9 为导航菜单项应用授权方案。

验证点:不同角色登录后,菜单中只出现其被授权访问的入口。

11.4.3 授权页面访问#

页面级访问控制通过页面的 Authorization Scheme 属性完成。Salary Review 页面设置为 HR Representatives Only 后,只有 HR 代表可以进入该页面。

图 11-10 将授权方案应用到页面。

菜单授权可以避免用户看到入口,但页面授权才是直接访问保护。即使用户手工修改浏览器地址访问该页面,未授权用户也会看到 “Access Denied by Page security check.” 错误。

图 11-11 非 HR 代表访问未授权页面时看到错误。

11.4.4 授权页面项或列访问#

授权方案也可以挂到具体列或页面项上。在 Employee Directory 页面中,将 SALCOMM 列的 Authorization Scheme 设置为 HR Representatives Only 后,HR 代表能看到薪资和佣金列,其他员工完全看不到这些列。

图 11-12 将授权方案应用到列。

验证点:普通员工打开同一报表时,敏感列不应出现在表头、列选择器或导出结果中。

11.4.5 授权按钮访问#

按钮的 Authorization Scheme 控制哪些用户能看到并使用按钮。在 Employee Directory 页面中,将 CREATE 按钮设置为 HR Representatives Only 后,只有 HR 代表能创建员工,其他用户看不到该按钮。

图 11-13 将授权方案应用到按钮。

如果按钮会提交页面并触发页面流程,应把同一授权方案也应用到对应页面流程,作为服务端的额外检查。CREATE 按钮跳转的 Employee 页面本身也应有页面级授权,避免用户绕过按钮直接访问。

11.4.6 授权编辑链接列访问#

Interactive Report 的编辑链接列也可以设置 Authorization Scheme。在 Employee Directory 页面中,将 Link Column 设置为 HR Representatives Only 后,只有 HR 代表能看到并点击编辑链接,其他用户无法发现编辑入口。

图 11-14 将授权方案应用到编辑链接列。

验证点:非 HR 用户既看不到编辑链接列,也不能手工访问链接目标页面;目标页面仍应保留页面级授权。

11.4.7 体验授权效果#

当授权方案应用到菜单、页面、列、按钮和编辑链接后,同一个应用会根据用户角色自动呈现不同体验。SUSAN 是 HR Representative,因此她能看到 Employee Directory 和 Salary Review,能查看 Salary 与 Commission 列,也能使用 Create 按钮和编辑链接。ADINA 是 App Admin,能访问 Employee Directory 和 Administration,但在员工目录里看不到薪酬信息,也不知道创建或编辑员工的入口。LUCY 作为普通员工,只能以简化的只读方式查看 Employee Directory。

图 11-15 最终用户的功能体验随角色自动调整。
图 11-16 普通员工看不到特定列、创建按钮和编辑链接。
图 11-17 HR 代表看到薪酬列、创建按钮和编辑链接。
图 11-18 只有 HR 代表可以使用 Salary Review 页面。

验证点:使用 SUSAN、ADINA、LUCY 分别登录,确认菜单、报表列、按钮、编辑链接和 Salary Review 页面访问结果都与角色匹配。

11.5 启用行级数据安全策略#

当需求不仅是“谁能进页面”,还包括“谁能看到哪些记录”时,需要行级数据安全。示例需求是:经理也可以访问 Salary Review;经理只能看到直接或间接下属;经理看到的数据只读。实现方式是新增授权方案,并结合 Oracle 数据库的 policy-driven row-level data security。

11.5.1 使用 SQL 和 PL/SQL 授权规则#

除了基于角色成员身份,APEX 授权方案还可以使用 SQL 或 PL/SQL。Woods HR 新增两个规则:

  • Manages Others:当前用户至少管理一名员工时授权。
  • HR Reps and Managers Only:当前用户是 HR 代表,或当前用户管理他人时授权。
图 11-19 新增两个使用 SQL 和 PL/SQL 的授权方案。

11.5.1.1 使用 SQL 定义授权规则#

Manages Others 使用 Exists SQL Query 方案类型。只要查询返回一行,就表示当前用户管理至少一名员工。

select 1
  from eba_demo_emp
 where mgr = (select empno
                from eba_demo_emp
               where ename = :APP_USER)
fetch first row only
图 11-20 使用 SQL 为经理定义授权方案规则。

验证点:用一个有下属的经理账号登录时规则返回授权;普通员工账号不应通过该规则。

11.5.1.2 使用 PL/SQL 定义授权规则#

HR Reps and Managers Only 使用 PL/SQL Function Returning Boolean 方案类型,把两个已有授权方案组合起来:

return apex_authorization.is_authorized('HR Representatives Only')
    or apex_authorization.is_authorized('Manages Others');

APEX_AUTHORIZATION.IS_AUTHORIZED 会以当前用户身份评估指定授权方案。由于两个被调用规则本身可设置为 Once per session,该组合规则也能受益于缓存后的判断结果。

图 11-21 使用 PL/SQL 表达式组合其他授权方案。

11.5.2 启用行级数据安全#

要在表或视图上定义行级安全策略,工作区解析模式需要数据库权限。策略由 DBMS_RLS 包管理;启用后,数据库会对访问该表或视图的语句透明地追加安全谓词。

11.5.2.1 确认 DBMS_RLS 执行权限#

工作区解析模式必须拥有 DBMS_RLSEXECUTE 权限。可先运行以下查询确认是否可以访问该包:

SELECT 'DBMS_RLS accessible' as result
FROM dual
WHERE EXISTS (
    SELECT 1 FROM all_objects
    WHERE object_name = 'DBMS_RLS'
    AND object_type = 'PACKAGE'
    AND owner = 'SYS')

如果结果为 No Rows Found,需要请 DBA 授权:

grant execute on dbms_rls to your_workspace_schema

11.5.2.2 定义安全策略函数#

行级安全策略把一个 security policy function 绑定到表或视图。该函数返回一段 WHERE 谓词文本,数据库会自动把它应用到对目标对象的访问中。

function my_policy_function (
    schema_var in varchar2,
    table_var  in varchar2)
    return        varchar2

返回 1=0 表示当前用户看不到任何行;返回 1=1 表示可以看到全部行;否则返回具体谓词来限制可见记录。Woods HR 的 ONLY_OWN_REPORTS 函数逻辑如下:HR 代表返回全部记录;经理返回其直接和间接下属;其他用户返回空集。

function only_own_reports(
    schema_var in varchar2,
    table_var  in varchar2)
    return         varchar2
is
    l_user_empno number;
    l_predicate varchar2(4000);
    l_apex_user varchar2(255);
begin
    l_apex_user := sys_context('APEX$SESSION','APP_USER');

    if l_apex_user is null then
        return '1=0';
    end if;

    if apex_authorization.is_authorized('HR Representatives Only') then
        return '1=1';
    end if;

    if not apex_authorization.is_authorized('Manages Others') then
        return '1=0';
    end if;

    begin
        select empno
          into l_user_empno
          from eba_demo_emp
         where ename = l_apex_user;
    exception
        when no_data_found then
            return '1=0';
    end;

    l_predicate := 'empno in (
        select empno
        from eba_demo_emp
        start with mgr = ' || l_user_empno || '
        connect by prior empno = mgr)';

    return l_predicate;
end only_own_reports;

验证点:HR 代表应能看到全部员工;经理只能看到管理链下的员工;无权限用户不应看到任何行。

11.5.2.3 添加并启用安全策略#

Employee Directory 仍需要显示所有员工,所以不要直接把策略加到原表上。为 Salary Review 创建一个专用视图 EBA_DEMO_EMP_V,再把行级安全策略绑定到这个视图。

create view eba_demo_emp_v as
select empno,
       ename,
       job,
       mgr,
       hiredate,
       sal,
       comm,
       deptno
from eba_demo_emp;

随后调用 DBMS_RLS.ADD_POLICY,把视图、策略名和策略函数关联起来:

begin
    begin
        dbms_rls.drop_policy(
            object_schema => sys_context('USERENV','CURRENT_USER'),
            object_name   => 'EBA_DEMO_EMP_V',
            policy_name   => 'ONLY_OWN_REPORTS_POLICY');
    exception
        when others then
            null;
    end;

    dbms_rls.add_policy(
        object_schema   => sys_context('USERENV','CURRENT_USER'),
        object_name     => 'EBA_DEMO_EMP_V',
        policy_name     => 'ONLY_OWN_REPORTS_POLICY',
        function_schema => sys_context('USERENV','CURRENT_USER'),
        policy_function => 'ONLY_OWN_REPORTS',
        statement_types => 'SELECT,INSERT,UPDATE,DELETE',
        update_check    => true,
        enable          => true);
end;

可用以下查询检查已应用的策略:

SELECT
    object_name,
    policy_name,
    function,
    policy_type,
    enable,
    sel, ins, upd, del,
    chk_option
FROM USER_POLICIES
ORDER BY object_name, policy_name

11.5.2.4 引用其他上下文信息#

安全策略函数除了调用 APEX_AUTHORIZATION.IS_AUTHORIZED,还可以读取 APEX 会话上下文来构造更通用的谓词。

  • 当前用户名:SYS_CONTEXT('APEX$SESSION','APP_USER')
  • 应用 ID:SYS_CONTEXT('APEX$SESSION','APP_ID')
  • 会话 ID:SYS_CONTEXT('APEX$SESSION','APP_SESSION')
  • 租户 ID:SYS_CONTEXT('APEX$SESSION','APP_TENANT_ID')

读取 APEX ACL 角色:

select role_name
  from apex_appl_acl_user_roles
 where user_name = sys_context('APEX$SESSION','APP_USER')
   and application_id = sys_context('APEX$SESSION','APP_ID')

读取外部身份提供商启用的动态组:

select group_name
  from apex_workspace_session_groups
 where apex_session_id = sys_context('APEX$SESSION','APP_SESSION')
   and user_name = sys_context('APEX$SESSION','APP_USER')

Tenant ID 可以在 After Authentication 应用流程或认证后过程中通过 APEX_SESSION.SET_TENANT_ID 设置。多租户应用可用它确保用户只访问自己公司的数据。

11.6 结合数据安全优化 Salary Review#

完成视图、行级安全策略和两个新增授权方案后,Salary Review 页面可以支持新需求:经理能进入页面,但只能看到自己管理链下的员工,并且薪资与佣金列只读;HR 代表仍能查看并编辑所有员工薪酬。

11.6.1 切换到启用数据安全的视图#

当区域基于带有行级安全策略的表或视图时,数据库会自动执行策略。把 Salary Review Interactive Grid 区域的 Table Name 从原表改为 EBA_DEMO_EMP_V,页面就会继承视图上的数据安全策略。

图 11-22 将 Salary Review 改为使用带数据安全策略的视图。

11.6.2 用授权规则驱动只读状态#

Salary Review 需要允许 HR 代表编辑 Salary 和 Commission,但经理只能只读查看自己的下属。可在这两列的 Read Only 表达式中使用:

not apex_authorization.is_authorized('HR Representatives Only')
图 11-23 除非用户是 HR 代表,否则 Sal 和 Comm 列只读。

验证点:经理可以打开页面但不能编辑薪资和佣金;HR 代表仍可编辑。

11.6.3 调整 Salary Review 页面访问#

把 Salary Review 页面的 Authorization Scheme 从仅 HR 代表访问改为 HR Reps and Managers Only,这样 HR 代表和经理都可以进入页面。

图 11-24 调整授权方案,让经理和 HR 代表都能访问。

11.6.4 为经理启用 Salary Review 菜单#

页面授权放开后,还需要把导航菜单项的 Authorization Scheme 同步改为 HR Reps and Managers Only。这样经理可以从菜单正常进入 Salary Review,而不是只能通过 URL 访问。

图 11-25 调整菜单项授权方案。

11.6.5 测试增强后的 Salary Review 页面#

运行时,授权方案和行级数据安全共同决定功能与数据范围。经理 JONES 登录后,菜单中会出现 Salary Review;打开页面后,他只看到直接或间接向他汇报的四名员工,并且 Sal 与 Comm 列只读。HR 代表 SUSAN 登录后,仍能看到所有员工并编辑薪资与佣金。

图 11-26 JONES 这样的经理现在能看到 Salary Review 页面。
图 11-27 数据安全确保 JONES 只看到自己的员工。

11.7 集成外部身份提供商#

APEX Accounts 适合快速内置认证,但很多组织已经在外部身份提供商中管理用户和角色。此时可以创建 Social Sign-in 类型的 Authentication Scheme,通过 OpenID Connect 或 OAuth 2.0 登录,并在认证后动态启用用户所属组。

示例使用 OCI Identity and Access Management (IAM) 中名为 WoodsHR 的 IAM domain。该域包含用户、组、用户与组的分配,以及允许 APEX 应用认证的 integrated application client。为了便于比较,外部身份提供商中配置与 APEX Accounts 示例相同的用户和角色结构。

注意:这里展示的基础 IAM 功能可在 OCI Always Free 租户中试验;更多 IAM 功能可能需要付费租户。

11.7.1 在 IAM Domain 中定义用户#

在 WoodsHR domain 的 User management 标签页中定义用户。为了与 APEX Accounts 示例保持一致,这里创建同一组用户名。

图 11-28 Identity Cloud Service 中的 Domain Users。

11.7.2 在 IAM Domain 中创建组#

OCI IAM 使用 group 表达 APEX 中 role 的概念。在 User management 标签页中,除了默认的 All Domain UsersDomain_Administrators,创建与 APEX 角色对应的三个组:EmployeeHR RepApp Admin

图 11-29 Identity Cloud Service 中的 Domain Groups。

11.7.3 将 IAM Domain 用户分配到组#

在组编辑页的 Users 标签页中把用户加入组。示例中八个用户都是 Employee 组成员;SUSAN 额外加入 HR Rep;ADINA 额外加入 App Admin。

图 11-30 Identity Cloud Service 中的 Domain Group Assignments。

验证点:外部组分配应与 APEX 角色示例保持同构,否则后续授权结果会不同。

11.7.4 为 APEX 配置 Confidential App#

在 IAM domain 的 Integrated applications 标签页中,创建允许 Woods HR APEX 应用通过该域认证的应用客户端。创建时提供 Woods HR APEX 应用 URL。

图 11-31 供 Woods HR APEX 应用使用的 Domain Integrated App。

随后编辑 OAuth 配置:

  • 选择 Configure this application as a client now
  • Allowed grant types 选择 Authorization code
  • Redirect URL 填写 APEX 实例的 /ords/apex_authentication.callback 绝对 URL。
  • Client type 选择 Confidential
  • 可按需要启用 Bypass consent,以跳过返回 profile 与 group 信息时的用户同意页。

配置完成后,会得到 Client ID、Client Secret、Domain URL 和 Discovery URL,例如 https://idcs-xx...xx.identity.oraclecloud.com/.well-known/openid-configuration

图 11-32 配置 Domain Integrated App OAuth Client。

11.7.5 为身份提供商定义凭据#

在创建 Social Sign-in 认证方案前,先在 Workspace Utilities 中定义 Web Credential。示例凭据 Woods HR OAuth 使用 Basic Authentication 类型,用来安全保存 OCI IAM confidential application 的 Client ID 和 Client Secret。建议在 Valid for URLs 中填写 IAM Domain URL,避免该凭据被误用于其他 URL。

图 11-33 用于 IDCS Social Sign-in Authentication 的 Web Credential。

11.7.6 使用外部提供商认证#

Web Credential 定义完成后,创建名为 Woods HR OAuthSocial Sign-in Authentication Scheme,并引用该 Web Credential。关键配置如下:

  • Credential Store:选择刚创建的 Web Credential。
  • Authentication Provider:选择 OpenID Connect Provider
  • Discovery URL:填写 IAM domain discovery URL。
  • Scope:填写 profile,groups
  • Username:使用 #sub#,以 IAM subject 作为 APEX username。
  • Convert Username To Upper Case:Yes。
  • Additional User Attributes:填写 groups
图 11-34 为 IDCS 配置 Social Sign-in Authentication Scheme。

11.7.7 在认证后过程中启用组#

外部身份提供商返回组信息后,需要在 post-authentication procedure 中把这些组注册为 APEX 动态组。Social Sign-in 认证方案的 Login Processing 标签页可以填写一个包过程名作为 Post-Authentication Procedure Name

图 11-35 配置认证后过程以启用组。

SUSAN 通过 OCI IAM 登录后,REST 响应中的 groups 属性包含她所属的组。每个对象的 name 属性就是要启用的组名。

{
  "family_name": "Sunshine",
  "given_name": "Susan",
  "groups": [
    {
      "id": "xxxxxxxxxxxx",
      "name": "Employee",
      "$ref": "http://dp-admin:9246/admin/v1/Groups/xxxxxxxxxxxx"
    },
    {
      "id": "yyyyyyyyyyyyy",
      "name": "HR Rep",
      "$ref": "http://dp-admin:9246/admin/v1/Groups/yyyyyyyyyyyyy"
    }
  ],
  "name": "Susan Sunshine",
  "preferred_username": "susan",
  "sub": "susan",
  "updated_at": 1755958517
}

示例包过程从最近解析的 APEX_JSON 文档中读取 groups 数组,把每个 name 推入字符串列表,然后调用 APEX_AUTHORIZATION.ENABLE_DYNAMIC_GROUPS

package eba_demo_woodshr_auth is
    procedure post_authentication;
end eba_demo_woodshr_auth;
--
package body eba_demo_woodshr_auth is
    function post_auth_json
    return json_object_t
    is
        l_ret json_object_t;
    begin
        if apex_json.g_values.count > 0 then
            apex_json.initialize_clob_output;
            apex_json.write( p_values => apex_json.g_values );
            l_ret := json_object_t(apex_json.get_clob_output);
            apex_json.free_output;
        else
            l_ret := json_object_t();
        end if;
        return l_ret;
    end post_auth_json;

    function get_object(
        p_array in json_array_t,
        p_index in pls_integer)
        return     json_object_t
    is
    begin
        return treat(p_array.get(p_index) as json_object_t);
    end get_object;

    procedure post_authentication
    is
        l_auth_data   json_object_t := post_auth_json;
        l_groups_arr  json_array_t;
        l_groups      apex_t_varchar2 := apex_t_varchar2();
    begin
        if     l_auth_data.has('groups')
           and l_auth_data.get('groups').is_array
        then
            l_groups_arr := l_auth_data.get_array('groups');
            for i in 0 .. l_groups_arr.get_size - 1 loop
                apex_string.push(l_groups,
                                 get_object(l_groups_arr,i)
                                 .get_string('name'));
            end loop;
            if l_groups.count > 0 then
                apex_authorization.enable_dynamic_groups(l_groups);
            end if;
        end if;
    end post_authentication;
end eba_demo_woodshr_auth;

如果外部提供商需要额外 API 才能取得组信息,可在认证后过程中使用 APEX_WEB_SERVICE.MAKE_REST_REQUEST 或 REST Data Source 获取组名,再动态启用。

11.7.8 从自定义代码获取应用组#

使用 ENABLE_DYNAMIC_GROUPS 后,需要在应用安全设置中把 Source for Role or Group Schemes 改为 Custom Code。入口是 Shared Components > Security Attributes,在 Authorization 标签页调整该设置。

图 11-36 将应用改为从自定义代码获取组。

11.7.9 将授权规则切换为 Custom#

启用动态组后,原来基于 Is In Role/Group 的授权方案需要把 Type 改为 Custom,这样规则会根据认证后过程注册的动态组来判断成员身份。示例中 Employee 授权方案被切换为 Custom。

图 11-37 将授权方案改为使用 Custom 类型解析动态组。

11.7.10 将 Social Sign-in 设为当前方案#

要在运行时试用新的认证方案,需要把 Woods HR OAuth Social Sign-in Authentication Scheme 设为当前方案。编辑该方案并点击 Make Current Scheme

图 11-38 将 Social Sign-in Authentication Scheme 设为当前方案。

更高级的场景可以启用 Switch in Session,再按用户动态决定使用哪个认证方案。

11.7.11 体验外部身份提供商#

完成配置后,应用具备以下组件:OCI IAM domain 中的用户、组、组分配和 confidential app;保存 client id 与 secret 的 Web Credential;带 OpenID Connect discovery URL 的 Social Sign-in 认证方案;启用动态组的认证后过程;使用 Custom Code 解析组的应用设置;以及切换为 Custom 类型的授权方案。

最终用户运行应用时,会先看到外部身份提供商的登录页。登录完成后,应用其余行为与使用 APEX Accounts 时一致,仍然按角色控制菜单、页面、列、按钮和数据访问。

图 11-39 用户现在使用 OCI IAM Sign In 登录 Woods HR。

11.8 检查授权规则上下文#

授权方案的 Evaluation Point 决定规则能使用多少上下文信息。Once per session 适合只依赖用户名和角色/组成员身份的判断;如果规则依赖会话期间可能变化的信息,使用 Once per page view 的 SQL 或 PL/SQL 规则可以引用标准绑定变量。

  • APP_USER:当前登录用户名;未登录时为 nobody。
  • APP_ID:当前应用 ID。
  • APP_ALIAS:当前应用别名。
  • APP_PAGE_ID:当前页面 ID。
  • APP_PAGE_ALIAS:当前页面别名。
  • WORKSPACE_ID:当前工作区 ID。

如果授权方案设置为 Once per componentAlways (No Caching),SQL 或 PL/SQL 还能引用当前组件信息:

  • APP_COMPONENT_TYPE:包含当前组件的字典视图名。
  • APP_COMPONENT_NAME:当前组件名。
  • APP_COMPONENT_ID:当前组件在字典视图中的唯一 ID。

这些上下文可以支持更通用、数据驱动的规则,例如由应用管理员在设置页面维护访问矩阵。为性能考虑,应缓存影响授权决策的唯一因素组合的结果。