`

数据库的细粒度访问控制

阅读更多

 

 

背景

根据控制对象的粗细程度,访问控制可分为粗粒度和细粒度两种 通常把规定访问整个数据库表或由基本表导出的视图的某个层称为粗粒度的访问控制,而细粒度控制则是把安全控制细化到数据库的行级或列级。

我们给银行上了一套系统,银行的政策允许所有财务经理可以访问所有账户持有人的信息,但在最近,对该政策做了改变只允许财务经理访问特定的客户集,那么为了使应用程序符合新的政策,我们必须对应用程序进行修改,有三种选择

1.          修改应用程序代码,使所有 SQL 语句都包含一个 WHERE 子句。但如果将来政策又有变化,则必须再一次修改代码,所以从长远考虑这不是一个好方法

2.          保持应用程序不动,用判定词创建表的视图,并用与表名一样的名字为这些视图创建同义词 。从应用程序不变更和安全性的角度来看这种方法比较好,但可能难于管理,因为有大量潜在的视图需要跟踪和管理

3.          保持应用程序不动,使用 Truman 模型实现。

 

文档术语

 

 

简称

英文

说明

RLS

Row Level Security

行级别安全性

VPD

Virtual Private database

虚拟专有数据库

同义词

synonym

别名的意思,类似视图。

就是一种映射关系

 

 

 

 

 

 

 

Truman 模型

U.C. Berkeley Shariq Rizvi 和其他人提出了 Truman 模型,该模型基于数据库级别修改查询。 Truman 模型的想法是为每个用户提供数据库的个人视图。为实现此目的,需要对用户的查询进行修改以确保用户不能查看允许之外的内容。

         Truman 模型:用户向数据库提交 SQL 语句,修改器拦截用户提交的语句,通过一定的策略修改语句后再执行。如下图:

    

 

Truman 模型下,相当于每个用户都拥有自己的私有数据库,用户在该数据库中进行数据管理(如查询,添加和修改数据)。

 

Truman 模型有时也称为细粒度访问控制 (FGAC) 行级安全 (RLS) 。(该模型名称的灵感源自于 1998 年的电影 The Truman Show Truman Burbank 角色所处的人工世界)。

该模型的优点包括:单点授权实施、可以拥有动态的集合、最终用户查询功能以及高效的数据处理(这是空间数据一个主要方面)。

Truman 模型的实现有 :

l   Oracle VP D

l   Research RLS

l   SQL Server RLS

Oracle RLS

Oracle 一直都提供授权(或拒绝)用户访问数据库对象的能力 , 但这些对象粒度只到表或视图这一级别。 Oracle8i 企业版中引入行级安全性,提供行级粒度的访问控制。 Oracle10G 中引入列级别安全性,提供列级粒度的访问控制。

行级安全性不是向对表有任何访问权限的用户打开整张表,而是将访问限定到表中特定的行。每个用户只能看到那些该用户被授权可以查看的数据。

VPD 包含两个要素:策略 Policy 策略函数( Policy Function

VPD 的策略

策略( Policy )用于管理(如添加,删除,修改)对哪些对象(表或视图)执行 RLS 控制。

VPD 包含的策略非常多,如添加策略,删除策略,刷新策略,启用策略,创建策略组,创建策略上下文等,更多策略及其详细内容参见 ORACLE DBMS_RLS 本文只详细讨论添加策略和删除策略。

添加策略

 

-- Apply the policy function to the table.

BEGIN

  DBMS_RLS.ADD_POLICY (object_schema     => 'scott',

                       object_name       => 'emp',

                       policy_name       => 'sp_job',

                       function_schema   => 'scott',

                       policy_function   => 'pf_job',

                       sec_relevant_cols => 'sal,comm');

END;

添加策略的所有属性如下:

l   Object_Name :表名、视图名或同义词

l   Object_Schema :用户名

l   Policy_name :策略名称

l   Policy_function :需要使用的策略函数

l   Function_schema :策略函数所属用户

l   Statement_type :应用策略的 DML, 可以是 select,insert,update,delete 的任意组合

l   Update_check :在 insert update 的时候是否检查。

l   Enable: 是否启用策略

l   Static_policy: 默认为 false, 设置为 true 时,该策略为任何访问该对象的人产生相同的谓词字符串。

l   Policy_type: 默认为 STATIC, 允许的值是 STATIC SHARED_STATIC CONTEXT_SENSITIVE SHARED_CONTEXT_SENSITIVE DYNAMIC

l   Long_predicate :该参数默认为 FALSE 。如果它为 TRUE ,谓词字符串最多可为 32K 字节长。否则,限制为 4000 字节

l   Sec_relevent_col 10G 新增,设置受保护的列,被设置的列的数据将不会显示,只能应用与表和视图,使用逗号或空格作为分隔符。假如 DML 语句中不含有设置的列,则忽略此策略。

l   sec_relevant_cols_opt 10G 新增, 允许在列级别 VPD 过滤查询中的行仍然出现在结果集中,敏感列返回 NULL 值。指定 DBMS_RLS.ALL_ROWS 显示所有列。

 

删除 策略

 

-- Remove the policy function from the table.

BEGIN

  DBMS_RLS.DROP_POLICY (object_schema     => 'scott', // 用户名

                        object_name       => 'emp', // 表名,视图名

                        policy_name       => 'sp_job'); // 策略名

END;

/

 

策略类型

正确的使用策略类型能提高 VPD 的效率,通过缓存策略函数的输出,使得随后的查询语句,不再执行策略函数, DBMS_RLS.ADD_POLICY 存储过程的策略类型参数可以设置 5 种策略类型中的一种。

Ø   静态类型:缓存策略函数的返回值,可以被个别对象重复利用,所以策略函数的返回值必须静态。

Ø   共享静态类型,同静态类型一样,但是生成的谓语能够被应用与多个对象。

Ø   敏感上下文类型:当策略基于本地应用上下文的时候使用,策略函数的结果被缓存和重复使用,只有当应用上下文改变的时候策略函数才会再一次执行。

Ø   共享敏感上下文:同敏感上下文类型一样,但是生成的谓语能够应用与多个对象。

Ø   动态类型:策略函数在每此执行 SQL 语句的时候都被执行。

 

VPD 策略函数

策略函数 Policy Function 用于设置判断条件,以过滤没有权限显示的行。

 

函数包定义

CREATE OR REPLACE PACKAGE exp_security AS

FUNCTION client_id_security(owner VARCHAR2, objname VARCHAR2)

   RETURN VARCHAR2;

END exp_security;

 

该函数的主体如下所示:

CREATE OR REPLACE PACKAGE BODY exp_security IS

FUNCTION client_id_security(owner VARCHAR2, objname VARCHAR2) RETURN VARCHAR2 IS predicate VARCHAR2(2000);

  BEGIN

    predicate := 'CLIENT_ID = sys_context(''THE_CTX'',''THE_CLIENT_ID'')';

    RETURN predicate;

  END client_id_security;

END;

 

Research RLS

Microsoft Research 最新发布的一篇文章讨论了 Truman 模型,本文提出了一种分配谓词授权的新方法。以下是一个授权查询示例:

 

GRANT SELECT employees // 策略定义

WHERE emp_id = user_id()// 授权模型

TO PUBLIC

因此,谓词将纳入到普通的授权语句中。这与 Oracle VPD 的实现相反, Oracle VPD 的实现是将策略定义( policy )与 SQL 授权模型( policy function )相分离。

 

SQLServer RLS

         SQL Server 中的行级安全性解决方案具有一定的侵入性。它需要为每一个数据表添加一个参数列,用于区分当前行的数据,属于哪一个用户或者角色。然后创建参数化的视图或者存储过程,传入适当的值。

具体实现步骤

1.         创建表,添加用于存储用户名的附加列 。如 Asset 资产表 , 添加 user_name 列。

2.         基于用户名列创建一个具有 WHERE 子句的视图

 

Create view V$ ASSET as select * from   Asset   where user_name =user_name ();

3.   基于视图创建用于查询,插入、更新和删除数据的存储过程

4.   对于插入数据的存储过程,使用 user_name () 函数捕获用户名并将该值插入 UserName 列。

5.   拒绝 public 角色对表和视图的所有权限。

6.          为数据库角色授予对存储过程的 EXECUTE 权限。 用户只能通过提供的存储过程访问数据。

 

参考资料

VPD 来保持信息的隐私

授权访问动态时空数据

Oracle VPD

虚拟专用数据库

 

SQL Server 中授予行级权限

 

转:http://kiral.iteye.com/blog/750819

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics