Public角色

Public角色
在本文中,我将通过描述几个安全场景来讨论如何使用Public角色以及Public角色怎么会导致你更多的难题。

Public角色相当于NT中的所有用户(Everyone)或验证用户组(Authenticated Users group)。所有加入到数据库中的用户会自动加入到角色中——即使是激活的guest用户也不例外。这就是说任何授予public角色的权限会自动扩展给所有用户。另外,你不能删除Public角色。Public角色可以不管角色的成员关系,快速地增加或删除所有用户的权限,这帮你省了不少事。

让我们看一个简单的情景:你有一个数据库,所有公司的人员都有数据库上的select、insert和delete权限。你可以通过下面的方法快速地实现:将权限授予Public角色,然后加入NT的EveyOne组到数据库中,这样他便自动成为public的成员了,这种方法既快又方便。

现在管理部门让你作第一次改变。你需要给“Trainees”组(新人组)只读权限;“AppUsers”组Select、Insert和Delete的权限;其他人不给任何权限。你该如何做?下面是一条方法:
1.删除数据库中的Everyone用户。
2.取消Public角色的Insert和Delete权限。
3.将AppUsers组作为用户添加到数据库中。
4.将Trainees组作为用户添加到数据库中。
5.创建一个AppUser角色,该角色拥有Insert和delete权限,将AppUsers组加入该角色。

此时,Trainees组因为仅仅属于public角色(自动的)而只有Select权限。AppUsers组因为属于AppUser角色和Public角色而拥有Select、Insert和Delete权限。不是Trainees和AppUsers组成员的NT用户没有任何权限。

又过了几个星期,管理部门告诉你未来几个星期里会有一个Contractor用户,此用户拥有email域名账号,而且能够访问数据库中的两个表。Contractor不是Trainees或AppUsers组中的成员。你该怎么办?一种可能的方法是:
1.在数据库中为Contractor增加一个用户。
2.创建一个Contractor角色,该角色拒绝数据库中的所有表,除了两个表。
3.将用户名Contractor加入到Contractor角色中。

希望你能看到现在的问题:因为public角色已拥有比我们期望给Contractor用户最小权限更多的权限了,我们不得不拒绝掉部门权限。这种做法没有什么不对的。但如果你不想使用拒绝(Deny),你就得重新思考你的权限了。如果可以从头再来,下面可能是个方法:
1.将AppUsers组作为用户添加到数据库中。
2.将Trainees组作为用户添加到数据库中。
3.将contractor作为用户添加到数据库中。
4.创建一个AppUser角色,该角色拥有Select、Insert和Delete权限。将AppUsers组加入该角色。
5.创建一个Trainees角色,该橘色拥有Select权限,并将Trainees组加入该角色。
6.创建一个Contractor角色,该角色在两个需要用到的表上有Select权限。将Contractor用户加入该角色。

这种方法的好处是权限非常清晰,比较容易学。不过,拥有一个基础的权限集还是很有用的。我目前的想法是自己创建一个“everyone”角色,其作用和Public差不多。通过将基础权限授予EveryOne来而不是Public,新用户不会轻易获得基础权限了。你必须明确将用户加入到一个或多个角色中。如果你将这种思想运行到目前的情形中,你可以如下实现:
1.将AppUsers组作为用户添加到数据库中。
2.将Trainees组作为用户添加到数据库中。
3.将contractor作为用户添加到数据库中。
4.创建一个AppUser角色,该角色拥有Insert和Delete权限。将AppUsers组加入该角色。
5.创建一个Trainees角色,并将Trainees组加入该角色。
6.创建一个Contractor角色,该角色在两个需要用到的表上有Select权限。将Contractor用户加入该角色。
7.创建一个EveryOne角色,该角色拥有所有表的Select权限。将AppUsers和Trainees组加入到此角色中。

这时可能的好处当然是,如果你不想再创建更多的角色,而且你认为这些角色至少能Select所有的表,这是你就可以使用everyone角色了。另一方面,如果你的设计改变,你想去除对一个或两个表的访问权限,你可以修改everyone,这样就可以影响到所有everyone成员了(不包括Contractor)。

在你真的决定继续本教程之前,你可能现在就想看一下Public的权限。你可以在企业管理器或查询分析器中执行下面这段代码:
select count(*) as PublicPermissionCount from sysprotects P inner join sysusers U on P.Uid = U.UID inner join sysobjects O on P.ID=O.ID where P.uid=0 and o.Type<>'S' and o.Name not like 'sys%' and O.Name not like 'sync%'

如果你不怎么熟悉sysprotects、sysobjects和syspermissions这些系统表,你可能想快速地浏览一下,以便能更好的理解这些表是如何一起工作的。这个查询依赖于Public角色的UID在sysprotects表中值总是0。因为我们不想修改系统表中权限,所以我们使用sysobjects表中的Type字段过滤掉系统表。在我的测试中,我发现SQL SERVER为复制(replication)功能使用的sync表也有public角色,所以我跳过了所有以“sync”打头的表。

如果你想在每个数据库中执行这段查询,那么使用sp_msforeachdb过程将比较理想。如果你以前没有使用过该过程,你可以参阅由Brian Knight写的文章

exec sp_msforeachdb @Command1="select '?' as DBName, count(*) as PublicPermissionCount from ?..sysprotects P inner join ?..sysusers U on P.Uid = U.UID inner join ?..sysobjects O on P.ID=O.ID where P.uid=0 and o.Type<>'S' and o.Name not like 'sys%' and O.Name not like 'sync%'

一旦你知道了数据库中授予给Public角色的权限,如果你想试试everyone角色,可以按下面的步骤进行:
1.    创建一个Everyone角色,将当前Public角色的所有的权限授予它。
2.    将所有的用户加入到everyone角色中。
3.    从Public中去除所有的权限。

不幸的是SQL 并没有提供将权限从一个角色拷贝至另一个角色的功能。我的第一个解决方法是将所有权限用脚本导出,使用查询和替换功能将“public”替换为“everyone”,然后再次运行脚本。虽然有点笨,但是还不错。或者你可以在企业管理器中通过权限对话框来点击选择。当然你也可以选择下载我写的的脚本

原文地址:
http://www.databasejournal.com/features/mssql/article.php/1478701/SQL-Permissions-The-Public-Role.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值