专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

Oracle 数据权限控制 - VPD 方案 oracle的权限主要有

ins518 2024-11-14 16:50:12 技术文章 7 ℃ 0 评论

我们知道,应用的功能模块权限控制相对比较简单,可以根据当前登陆用户,在界面上控制菜单是否呈现、按钮是否可用、后台权限拦截器 等方式来实现。

数据权限控制往往比较麻烦。

通常的做法可能是根据当前登陆用户,在 SQL 中动态的拼接 WHERE 条件来实现。这样对应用不透明,很容易遗漏从而造成安全风险,当然也比较难维护。这里介绍一下Oracle数据库中以策略声明的方式自动的控制数据访问权限,对应用代码是透明的。

要实现数据权限的控制,关键是把当前的应用登陆用户放到数据库连接的会话中,从而在数据库端可以根据当前的登陆用户,执行相应的权限。

以下是具体的步骤。

数据安全控制


对于数据安全部分,该解决方案使用 VPD 实现基于用户的数据安全控制。我们指定了 3 个用户用于演示目的:

  • demo_admin:拥有所有数据访问权限。
  • 北部:只能访问属于“北部地区”的公司数据
  • 南部:只能访问属于“南部地区”的公司的数据

本方案实现了这样一种“细粒度”的数据访问控制,即按照应用登录用户(而非数据库用户)进行访问。这里的核心点是如何将应用登录用户绑定到当前数据库会话上。具体实现步骤如下:

首先,我们创建一个上下文,用于存储应用程序用户/登录信息,例如:

CREATE OR REPLACE CONTEXT APP_USER_CTX USING SET_APP_USER_CTX_PROC;

其次,在上面的语句中我们指定了一个过程SET_APP_USER_CTX_PROC,所以现在让我们定义该过程:

CREATE OR REPLACE PROCEDURE SET_APP_USER_CTX_PROC(app_user IN VARCHAR2)
IS 
BEGIN
 DBMS_SESSION.SET_CONTEXT('APP_USER_CTX', 'APP_USER', app_user);
END;

第三,我们来定义VPD策略:

CREATE OR REPLACE FUNCTION F_POLICY_DATA_BY_REGION (
 schema IN VARCHAR2,
 tab IN VARCHAR2
) RETURN VARCHAR2 IS
 v_login VARCHAR2(256);
 v_region VARCHAR2(256);
 predicate varchar2(4000);
BEGIN
 v_login := sys_context('APP_USER_CTX', 'APP_USER');
IF v_login is NULL THEN
 return NULL;
 END IF;
BEGIN
 SELECT
 loc
 INTO v_region
 FROM
 fsc_user_loc
 WHERE
 upper(login) = upper(v_login);
EXCEPTION
 WHEN no_data_found THEN
 v_region := '全国';
 END;
IF v_region IS NOT NULL AND v_region <> '全国' THEN
 predicate := '销售区域=''' || v_region || '''';
 END IF;
 
 return predicate;
END; 

最后,让我们将策略绑定到我们的数据(表/视图),例如

BEGIN
 dbms_rls.add_policy(
 object_schema => 'HYSUN', 
 object_name => '服务分类汇总数据', 
 policy_name => 'query_aggdata_by_region', 
 policy_function => 'F_POLICY_DATA_BY_REGION', 
 statement_types => 'SELECT'
 );
END;

现在一切都设置好了。那么如何将用户登录名设置到数据库会话中呢?答案是,

在应用程序中,当获得数据库连接时,在查询数据之前调用SET_APP_USER_CTX_PROC过程。这与以下非常相似:

exec SET_APP_USER_CTX_PROC(app_user => 'hysun');

执行完上述语句后,可以通过执行以下语句查看数据库会话中当前应用的用户名是'hysun':

select SYS_CONTEXT ('APP_USER_CTX', 'APP_USER') from dual;

因此,您只需根据登录用户/角色在应用程序中定义数据访问映射,然后 VPD 将帮助您控制数据访问。此外,这对应用程序来说是透明的,意味着您无需为不同的用户/角色编写不同的 SQL(where 子句),VPD 将帮助您完成此类工作。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表