4.6.6 权限的收回

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
2
3
revoke select
on department
from Amit,Satoshi restrict;

注意一些数据库实现不支持上述语法;它们采用另一种方式:收回权限本身,然后不带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角色。