视图及其授权
在本文中,我们将和大家一起讨论视图及其授权,我们会用几个例子向大家展示如何赋予视图的权限以及什么情况下我们需要使用“WITH GRANT OPTION”语句。
问题描述
- 有三个用户,分别是用户A,用户B和用户C,每个用户拥有自己的schema
- 用户A在自己的schema下面创建了表A,然后将表A的select权限赋予了用户B
- 用户B基于表A在自己的schema下面创建了视图B
- 现在问题来了。用户B可以将视图B的select权限赋给用户C吗?那么用户C是否又能看到视图B中的数据呢?
在回答这些问题之前,让我们先在SAP HANA里面做几个实验。本文的测试案例所使用的SAP HANA版本为SAP HANA SPS8 Revision 80。
实验一
步骤一:使用SYSYEM用户创建三个用户,分别是USER_A, USER_B和USER_C
CREATE USER USER_A PASSWORD Initial1;
CREATE USER USER_B PASSWORD Initial1;
CREATE USER USER_C PASSWORD Initial1;
步骤二:使用USER_A在自己的schema USER_A下面创建TABLE_A,然后将该表的select权限赋给USER_B
CREATE COLUMN TABLE USER_A.TABLE_A (ID INTEGER);
GRANT SELECT ON USER_A.TABLE_A TO USER_B;
步骤三:使用USER_B在自己的schema USER_B下面创建基于TABLE_A的视图VIEW_B
CREATE VIEW USER_B.VIEW_B AS SELECT * FROM USER_A.TABLE_A;
步骤四:使用USER_B尝试给USER_C赋予VIEW_B的select权限,但是失败
GRANT SELECT ON USER_B.VIEW_B TO USER_C;
VIEW_B是USER_B创建的,那么为什么USER_B不能给USER_C赋予VIEW_B的select权限呢?
原因很简单。虽然VIEW_B是USER_B创建的,但是VIEW_B是基于TABLE_A的,而USR_C对于TABLE_A是没有任何权限的。试想一下,如果USER_B成功运行了步骤四中的SQL语句,那么权限将不复存在。因为任何用户都可以使用这种手段来看到任何表,比如该例中,USER_C就可以通过USER_B来创建视图的方法让其看到TABLE_A中的内容。
那么有什么办法可以让USER_C拥有VIEW_B的select权限吗?有,而且十分简单。我们只需要让USER_A给USER_B说点什么,比如:
“兄弟,你可以自己玩我的篮球(TABLE_A),如果你和其他人(USER_C)有篮球比赛(VIEW_B),你也可以用我的篮球。”
这意味着USER_A同意USER_B让其他人一起玩USER_A的篮球。在这种场景中,我们就可以使用“WITH GRANT OPTION”了,这句语句允许被授权的人继续授权给其他人。那么,让我们来试一下。
步骤五:使用USER_A重新给USER_B赋予TABLE_A的select权限,这次我们加上“WITH GRANT OPTION”
GRANT SELECT ON USER_A.TABLE_A TO USER_B WITH GRANT OPTION;
步骤六:使用USER_C成功查看VIEW_B
SELECT * FROM USER_B.VIEW_B;
实验二
现在让我们来看另外一个例子。在这个例子中,我们先让USER_A把TABLE_A的select权限赋给USER_C,看看会发生什么。
步骤一:使用SYSTEM创建三个用户,分别是USER_A, USER_B和USER_C
CREATE USER USER_A PASSWORD Initial1;
CREATE USER USER_B PASSWORD Initial1;
CREATE USER USER_C PASSWORD Initial1;
步骤二:使用USER_A在自己的schema USER_A下面创建TABLE_A,然后将该表的select权限赋给USER_B和USER_C
CREATE COLUMN TABLE USER_A.TABLE_A (ID INTEGER);
GRANT SELECT ON USER_A.TABLE_A TO USER_B;
GRANT SELECT ON USER_A.TABLE_A TO USER_C;
步骤三:使用USER_B在自己的schema USER_B下面创建基于TABLE_A的视图VIEW_B,并且将整个schema USER_B的select权限赋给USER_C
CREATE VIEW USER_B.VIEW_B AS SELECT * FROM USER_A.TABLE_A;
GRANT SELECT ON SCHEMA USER_B TO USER_C;
步骤四:使用USER_C尝试查看VIEW_B,但是失败
SELECT * FROM USER_B.VIEW_B;
这次为什么失败呢?现在你可能有些困惑,你可能这么认为:
1.因为USER_A把TABLE_A的select权限赋予了USER_C,所以USER_C应该可以查看TABLE_A。对,你说的没错。USER_C可以成功运行如下语句:
SELECT * FROM USER_A.TABLE_A;
2.因为USER_B把自己整个schema USER_B的select权限赋给了USER_C,所以USER_C应该可以查看schema USER_B下面的所有对象。这个观点正确吗?从步骤四中的错误信息可以得出这个观点是错误的。那么错在哪里呢?
我们还是举篮球的例子。
- USER_A对USER_B说,“USER_B,你可以玩我的篮球。”
- USER_A对USER_C说,“USER_C,你可以玩我的篮球。”
- USER_B对USER_C说,“USER_C,你可以一直和我一起玩篮球。”
如果USER_C和USER_B一起玩USER_B的篮球,那么没有任何问题。但是如果USER_B在玩USER_A的篮球,此时USER_C可以加入一起玩吗?不行,因为USER_A没有同意USER_B让其他人一起玩USER_A的篮球。这就是原因所在。那么,我们还是需要使用“WITH GRANT OPTION”来解决该问题。
步骤五:使用USER_A重新给USER_B赋予TABLE_A的select权限,这次我们加上“WITH GRANT OPTION”
GRANT SELECT ON USER_A.TABLE_A TO USER_B WITH GRANT OPTION;
步骤六:使用USER_C成功查看VIEW_B
SELECT * FROM USER_B.VIEW_B;
实验三
假设我们现在多了一个用户USER_D。USER_C想在自己的schema USER_C下面创建一个基于VIEW_B的视图VIEW_C,而且想让USER_D查看VIEW_C。那么我们应该运行哪些SQL来实现这个需求呢?大家可以把这个实验当做课后练习,这里我们就不具体解释了,代码如下:
–SYSTEM
CREATE USER USER_A PASSWORD Initial1;
CREATE USER USER_B PASSWORD Initial1;
CREATE USER USER_C PASSWORD Initial1;
CREATE USER USER_D PASSWORD Initial1;
–USER_A
CREATE COLUMN TABLE USER_A.TABLE_A (ID INTEGER);
GRANT SELECT ON USER_A.TABLE_A TO USER_B WITH GRANT OPTION;
–USER_B
CREATE VIEW USER_B.VIEW_B AS SELECT * FROM USER_A.TABLE_A;
GRANT SELECT ON USER_B.VIEW_B TO USER_C WITH GRANT OPTION;
–USER_C
CREATE VIEW USER_C.VIEW_C AS SELECT * FROM USER_B.VIEW_B;
GRANT SELECT ON USER_C.VIEW_C TO USER_D;
–USER_D
SELECT * FROM USER_C.VIEW_C;
总结
基于以上的实验,我们现在来回答文章开头的问题。
- 如果你的视图是基于其他不是由你创建的对象,然后你想让其他人能够查看你的视图,那么你需要让基于对象的拥有者在给你赋权限的时候加上“WITH GRANT OPTION”
- 另外,你拥有对整个schema的select权限并不意味这你可以查看这个schema下面所有的对象
同样,你可以访问SAP HANA开发者指南得到相似的答案 Object Privileges – SAP HANA Developer Guide – SAP Library,下面将其翻译成中文。
“一些数据库对象是基于其他对象的,比如视图通常定义为对其他表和视图的查询。对于有依赖对象操作的赋权需要对该对象和其所依赖对象的权限。对于视图来说,SAP HANA实现了标准的SQL行为。一个用户拥有对一个视图操作的赋权需要满足如下两点:
- 用户被赋予操作该视图的权限或者角色
- 该视图的拥有者对于该视图依赖的对象具有WITH GRANT OPTION赋权”
声明:本文所介绍的视图及其权限是一种通用的机制和原理,不仅仅适用于SAP HANA,其他数据库同样适用,比如Oracle。
想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!
转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2014/11/18/%E8%A7%86%E5%9B%BE%E5%8F%8A%E5%85%B6%E6%8E%88%E6%9D%83,请勿用于任何商业用途。