Sql-Server

這是否意味著“公眾”擁有完全的選擇、插入、更新和刪除權限?

  • June 25, 2013

我正在嘗試創建一個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'

並得到這些結果:

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

這是否意味著無論登錄到數據庫的任何人都將擁有基於“公共”權限的完全訪問權限?

這意味著,如果使用者沒有為公共具有權限的安全對象(或從明確設置的權限繼承)明確設置權限,則將應用這些權限。換句話說,如果您對User1具有DELETE拒絕權限User_TableUser1則將無法從該表中刪除數據。

請參閱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

引用自:https://dba.stackexchange.com/questions/31247