为不同的SQL Server架构设置用户权限


16

我需要限制对特定用户的访问,但是他们仍然需要能够查看dbo拥有的表中的数据。

我正在尝试执行以下操作:

  1. dbo模式具有正常功能,可以访问所有内容
  2. schema1模式只能访问schema1对象
  3. 如果schema1视图或存储过程访问dbo拥有的表中的数据,则权限链会适当
  4. user1有权访问schema1,除此之外没有其他权限;#3除外

这是我尝试过的:

  1. 创建一个使用随机密码映射到测试登录名的user1用户
  2. 在dbo模式中创建了几个表,其中包含一些测试数据
  3. 创建一个schema1模式
  4. 创建一个schema1.get_profiles,该视图从一个名为schema1.profiles的视图中进行选择,该视图访问dbo.people,dbo.taglinks和dbo.tags中的数据

但是,以user1身份登录时使用以下语句:

EXEC get_profiles 1

结果是:

The SELECT permission was denied on the object 'tags', database 'schema_test', schema 'dbo'.

我已经尝试过WITH EXECUTE AS OWNER并且无法开始理解“所有权链接”应该如何工作。

我也尝试过

GRANT EXECUTE ON SCHEMA::schema1 TO user1
GRANT INSERT ON SCHEMA::schema1 TO user1
GRANT SELECT ON SCHEMA::schema1 TO user1
GRANT UPDATE ON SCHEMA::schema1 TO user1
GRANT VIEW DEFINITION ON SCHEMA::schema1 TO user1

但出现以下错误(尽管是具有dbo级访问权限的用户):

Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.

我需要的是user1能够通过我给它的存储过程访问数据,而没有别的。

此外,它最终旨在存在于现有的SQL Azure数据库上,但是我首先要针对本地虚拟数据库进行测试。


请参阅我的回答:如何对用户隐藏架构让我知道是否需要更多说明。
Kin Shah 2013年

1
这似乎让我更清楚了。我认为问题是我将Schema1的所有者设置为User1,而不是dbo。我将Schema1设置为User1所拥有,对其进行了调整并遵循了该问题,并且能够使某些工作正常进行。如果需要,您可以提出问题的答案。谢谢!
朱莉娅·麦奎根

很高兴它对您有所帮助。
Kin Shah

Answers:


17

基本概念是使用GRANT / DENY Schema Permissions。您可以通过创建角色然后向其中添加成员来有效地管理权限。

下面是一个示例,将详细说明您

use master
go
--Create Logins
CREATE LOGIN UserA WITH Password='UserA123';
go
CREATE LOGIN UserB WITH Password='UserB123';

use AdventureWorks2008R2
go
--Create Database Users
CREATE USER UserA;
go
CREATE USER UserB;
go
--Create the Test Schemas
CREATE SCHEMA SchemaA AUTHORIZATION UserA
go
CREATE SCHEMA SchemaB AUTHORIZATION UserB
go

-- create test tables
create table schemaA.TableA (fname char(5))
go
insert into schemaA.TableA (fname) values ('Kin-A')
go

create table SchemaB.TableB (fname char(5))
go
insert into SchemaB.TableB (fname) values ('Kin-B')
go

现在测试:

--Test for UserA in SchemaA
EXEC('select * from schemaA.TableA') AS USER = 'UserA'
go
--Kin-A

-- Test for UserB in SchemaB == this should fail
EXEC('select * from SchemaB.TableB') AS USER = 'UserA'
go
--Msg 229, Level 14, State 5, Line 1
--The SELECT permission was denied on the object 'TableB', database 'AdventureWorks2008R2', schema 'SchemaB'.

现在创建存储过程:

CREATE PROCEDURE SchemaB.proc_SelectUserB
AS
    select * from schemaA.TableA;
go
create procedure schemaA.proc_SchemaA
as 
    select * from schemaA.TableA

现在向模式B的SP授予对UserA的执行权限

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [UserA] 
go

测试它以查看UserA是否能够从schemaB运行SP。这将通过

EXECUTE AS LOGIN='UserA';
    Exec SchemaB.proc_SelectUserB;
    revert;
go
--- Kin-A

但是UserA将无法查看SchemaB中的数据

EXECUTE AS LOGIN='UserA';
    select * from SchemaB.TableB
revert;
go

--- Msg 229, Level 14, State 5, Line 3
--- The SELECT permission was denied on the object 'TableB', database 'AdventureWorks2008R2', schema 'SchemaB'.

或者,您可以使用DATABASE ROLE并仅向其中添加用户以提高权限的可管理性:

EXEC sp_addrole 'SchemaBUsesSchemaAProc'
go
EXEC sp_addrolemember 'SchemaBUsesSchemaAProc','UserA';
go

下面的语句将确保UserA能够看到schemaA和NOT schemaB。好消息是,您可以仅将用户添加到SchemaBUsesSchemaAProc角色,他们将继承授予该角色的所有权限。

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

如果仅允许UserA执行SchemaB拥有的SP,则以下语句将完成此工作:

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [SchemaBUsesSchemaAProc] 
go

这样,UserA无法看到SchemaB的表,但仍可以从SchemaB执行proc。

下面将解释权限层次结构

在此处输入图片说明


2
重申一下,两个模式都由同一用户拥有很重要。那是我遇到的主要问题。
朱莉娅·麦奎根
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.