Establecer permisos de usuario para diferentes esquemas de SQL Server

16

Necesito limitar el acceso a un usuario en particular, pero aún necesitan poder ver los datos en tablas propiedad de dbo.

Estoy tratando de hacer lo siguiente:

  1. El esquema dbo funciona como lo haría normalmente, tiene acceso a todo
  2. schema1 schema tiene acceso solo a objetos schema1
  3. Si una vista de esquema1 o un procedimiento almacenado accede a los datos en tablas propiedad de dbo, la cadena de permisos de manera adecuada
  4. el usuario1 tiene acceso al esquema1, y nada más; excepto en el caso del n. ° 3

Esto es lo que he intentado:

  1. Crear un usuario1 usuario asignado a un inicio de sesión de prueba con una contraseña aleatoria
  2. Creé un par de tablas en el esquema dbo con algunos datos de prueba en ellas
  3. Creó un esquema de esquema1
  4. Creó un schema1.get_profiles que selecciona desde una vista llamada schema1.profiles que accede a datos en dbo.people, dbo.taglinks y dbo.tags

Sin embargo, utilizando la siguiente instrucción mientras está conectado como usuario1:

EXEC get_profiles 1

resultados en:

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

He intentado WITH EXECUTE AS OWNERy no puedo comenzar a entender cómo se supone que funciona el "encadenamiento de propiedad".

También he intentado

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

pero recibo el siguiente error (a pesar de ser un usuario con acceso de nivel dbo):

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

Lo que necesito es user1 para poder acceder a los datos a través de los procedimientos almacenados que le doy, y nada más.

Además, esto está destinado a vivir eventualmente en una base de datos SQL Azure existente, pero primero estoy probando contra una base de datos ficticia local.

Julia McGuigan
fuente
Consulte mi respuesta: Cómo ocultar el esquema del usuario Avíseme si necesita más aclaraciones.
Kin Shah
1
Esto parece aclararme más. Creo que el problema era que tenía el propietario de Schema1 configurado en Usuario1, en lugar de dbo. Configuré que Schema1 fuera propiedad de Usuario1, adapté y seguí la pregunta, y pude hacer que algo funcionara. Puede proponer una respuesta a la pregunta si lo desea. ¡Gracias!
Julia McGuigan el
Me alegro de que te haya ayudado.
Kin Shah

Respuestas:

17

El concepto básico es utilizar los permisos de esquema GRANT / DENY . Puede administrar los permisos de manera eficiente al crear un rol y luego agregarle miembros.

A continuación se muestra un ejemplo que lo explicará en detalle.

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

Ahora prueba:

--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'.

Ahora cree procedimientos almacenados:

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

Ahora otorgue permisos de ejecución al usuario A en el SP de schemaB

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

Pruébelo ... para ver si el usuario A puede ejecutar SP desde el esquema B. Esto pasará

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

Pero el usuario A no podrá ver los datos de 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'.

Alternativamente, puede usar DATABASE ROLE y simplemente agregar usuarios para una mejor capacidad de administración de permisos:

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

La siguiente declaración se asegurará de que el usuario A pueda ver el esquema A y NO el esquema B. Lo bueno es que solo puede agregar usuarios al SchemaBUsesSchemaAProcrol y heredarán todos los permisos otorgados a ese rol.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

Si solo desea permitir que el usuario A ejecute SP que son propiedad de SchemaB, la siguiente declaración hará el trabajo:

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

De esta forma, el usuario A no puede ver las tablas de SchemaB, pero aún puede ejecutar procs desde SchemaB.

A continuación se explicará la jerarquía de permisos :

ingrese la descripción de la imagen aquí

Kin Shah
fuente
2
Solo para reiterar, es importante que ambos esquemas sean propiedad del mismo usuario. Ese era el problema principal que estaba teniendo.
Julia McGuigan