这是否意味着“公共”具有完全选择、插入、更新和删除访问权限?

Pro*_*eur 3 sql-server-2008 security sql-server permissions sql-server-2008-r2

我正在尝试创建一个SQL Server 2008 R2只能从一个 SQL 视图中进行选择的新数据库用户。但是,无论我在以这个新用户身份登录时尝试什么,我都可以从任何表中进行选择。我运行了这个查询:

select  princ.name
,       princ.type_desc
,       perm.permission_name
,       perm.state_desc
,       perm.class_desc
,       object_name(perm.major_id)
from    sys.database_principals princ
left join
        sys.database_permissions perm
on      perm.grantee_principal_id = princ.principal_id
WHERE princ.name = 'public'
AND object_name(perm.major_id) = 'User_Table'
Run Code Online (Sandbox Code Playgroud)

并得到这些结果:

name    type_desc       permission_name     state_desc  class_desc          (No column name)
public  DATABASE_ROLE   DELETE              GRANT       OBJECT_OR_COLUMN    User_Table
public  DATABASE_ROLE   INSERT              GRANT       OBJECT_OR_COLUMN    User_Table
public  DATABASE_ROLE   REFERENCES          GRANT       OBJECT_OR_COLUMN    User_Table
public  DATABASE_ROLE   SELECT              GRANT       OBJECT_OR_COLUMN    User_Table
public  DATABASE_ROLE   UPDATE              GRANT       OBJECT_OR_COLUMN    User_Table
Run Code Online (Sandbox Code Playgroud)

这是否意味着无论登录到数据库的任何人都具有基于“公共”权限的完全访问权限?

Tho*_*ger 6

这意味着如果用户没有为public具有权限的安全对象(或从显式设置的权限继承)明确设置权限,则将应用这些权限。换句话说,如果你有User1使用DELETE权限否认User_Table,那么User1将无法从该表中删除数据。

请参阅BOL 关于数据库级角色的参考

公共数据库角色
每个数据库用户都属于公共数据库角色。当用户尚未被授予或拒绝对某个安全对象的特定权限时,该用户将继承授予 public 的对该对象的权限。

例子

use TestDB;
go

create login Login1
with
    password = 'password',
    check_policy = off;
go

create user User1
for login Login1;
go

-- this will return 1 (meaning, yes it is a role member)
select is_rolemember('public', 'User1');


-- let's do a test to show the above theory
create table SomeTable
(
    id int identity(1, 1) not null,
    SomeText varchar(30) not null
        default replicate('a', 30)
);
go

insert into SomeTable
values(default);
go 10

-- give the public role permissions to SELECT on SomeTable
grant select
on SomeTable
to public;
go

-- this will be successful, because User1 is part of public
execute as user = 'User1';
go

select *
from SomeTable;

revert;
go


-- create a new role to deny SELECT on SomeTable
exec sp_addrole 'Role1';
go

deny select
on SomeTable
to Role1;
go

-- add User1 to this new role
exec sp_addrolemember 'Role1', 'User1';
go


-- this will not be successful because User1 now has been denied SELECT on SomeTable
execute as user = 'User1';
go

select *
from SomeTable;

revert;
go
Run Code Online (Sandbox Code Playgroud)