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

Jul*_*gan 16 sql-server-2008 sql-server stored-procedures

我需要限制对特定用户的访问,但他们仍然需要能够查看 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
Run Code Online (Sandbox Code Playgroud)

结果是:

The SELECT permission was denied on the object 'tags', database 'schema_test', schema 'dbo'.
Run Code Online (Sandbox Code Playgroud)

我已经尝试过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
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误(尽管是具有 dbo 级别访问权限的用户):

Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.
Run Code Online (Sandbox Code Playgroud)

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

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

Kin*_*hah 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
Run Code Online (Sandbox Code Playgroud)

现在测试:

--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'.
Run Code Online (Sandbox Code Playgroud)

现在创建存储过程:

CREATE PROCEDURE SchemaB.proc_SelectUserB
AS
    select * from schemaA.TableA;
go
create procedure schemaA.proc_SchemaA
as 
    select * from schemaA.TableA
Run Code Online (Sandbox Code Playgroud)

现在在 schemaB 的 SP 上授予 UserA 执行权限

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [UserA] 
go
Run Code Online (Sandbox Code Playgroud)

测试一下.. 看看UserA 是否能够从schemaB 运行SP。这将通过

EXECUTE AS LOGIN='UserA';
    Exec SchemaB.proc_SelectUserB;
    revert;
go
--- Kin-A
Run Code Online (Sandbox Code Playgroud)

但是 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'.
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用 DATABASE ROLE 并将用户添加到其中以更好地管理权限:

EXEC sp_addrole 'SchemaBUsesSchemaAProc'
go
EXEC sp_addrolemember 'SchemaBUsesSchemaAProc','UserA';
go
Run Code Online (Sandbox Code Playgroud)

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

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go
Run Code Online (Sandbox Code Playgroud)

如果您只想允许 UserA 执行 SchemaB 拥有的 SP,那么下面的语句将完成这项工作:

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [SchemaBUsesSchemaAProc] 
go
Run Code Online (Sandbox Code Playgroud)

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

下面将解释权限层次结构

在此处输入图片说明

  • 重申一下,重要的是两个模式都归同一个用户所有。这是我遇到的主要问题。 (2认同)