4.6.6 权限的收回
假设数据库管理员决定收回用户U1的授权。由于U4从U1处获得过授权,因此其权限也应该被收回。可是,U5既从U1处又从U2处获得过授权。由于数据库管理员没有从U2处收回teaches
上的更新权限,U5继续拥有teaches
上的更新权限。如果U2最终从U5处收回授权,则U5失去权限。
对狡猾的用户可能企图通过相互授权来破坏权限收回规则。例如,如果U2最初由数据库管理员授予了一种权限,U2进而把此权限授予给U3。假设U3现在把此权限授回给U2。如果数据库管理员从U2收回权限,看起来好像U2保留了通过U3获得的授权。然而,注意一旦管理员从U2收回权限,在授权图中就不存在从根到U2或U3的路径了。这样,SQL
保证从这两个用户那里都收回了权限。
默认级联收回
正如我们刚才看到的那样,从一个用户/角色那里收回权限可能导致其他用户/角色也失去该权限。这一行为称作级联收回。在大多数的数据库系统中,级联是默认行为。
如何防止级联回收
然而, revoke
语句可以申明restrict
来防止级联收回:
1 | revoke select |
注意一些数据库实现不支持上述语法;它们采用另一种方式:收回权限本身,然后不带grant option
重新授权。
级联收回的问题
级联收回在许多情况下是不合适的。假定Satoshi
具有dean
角色,他将instructor
授给Amit
,后来dean
角色从Satoshi
收回(也许由于Satoshi
离开了大学);Amit
继续被雇佣为教职工,并且还应该保持dean
角色。
通过一个角色来授权
为了处理以上情况,SQL
允许权限由一个角色授予,而不是由用户来授予。SQL
有一个与会话所关联的当前角色的概念。默认情况下,一个会话所关联的当前角色是空的(某些特殊情况除外)。
将会话和当前角色进行关联
执行set role role_name
可以设置一个会话所关联的当前角色。这个指定的角色必须已经授予给用户,否则set role
语句执行失败。
如何授权给角色
如果要在授予权限时将授权人设置为一个会话所关联的当前角色,并且当前角色不为空的话,我们可以在授权语句后面加上:
1 | granted by current_role |
子句
授权给角色可以避免级联回收的问题
假设将角色instructor
(或其他权限)授给Amit
是用granted by current_role
子句实现的,当前角色被设置为dean
而不是授权人(用户Satoshi
),这样,即使在Satoshi
的权限被收回后,Amit
仍然能够保持instructor
角色。
原文链接: 4.6.6 权限的收回