Impostazione delle autorizzazioni utente per diversi schemi di SQL Server


16

Devo limitare l'accesso a un determinato utente, ma devono comunque essere in grado di vedere i dati nelle tabelle di proprietà di dbo.

Sto provando a fare quanto segue:

  1. lo schema dbo funziona come normalmente, ha accesso a tutto
  2. schema1 schema ha accesso solo agli oggetti schema1
  3. se una vista schema1 o una procedura memorizzata accede ai dati nelle tabelle di proprietà di dbo, la catena di autorizzazioni in modo appropriato
  4. user1 ha accesso a schema1 e nient'altro; tranne nel caso del n. 3

Ecco cosa ho provato:

  1. Creare un utente user1 associato a un login di prova con una password casuale
  2. Creato un paio di tabelle nello schema dbo con alcuni dati di test al loro interno
  3. Creato uno schema1
  4. Creato uno schema1.get_profiles che seleziona da una vista chiamata schema1.profiles che accede ai dati in dbo.people, dbo.taglinks e dbo.tags

Tuttavia, utilizzando la seguente istruzione durante l'accesso come utente1:

EXEC get_profiles 1

risulta in:

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

Ho provato WITH EXECUTE AS OWNERe non riesco a capire come dovrebbe funzionare il "concatenamento della proprietà".

Ho anche provato

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

ma viene visualizzato il seguente errore (nonostante sia un utente con accesso a livello di doppio):

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

Ciò di cui ho bisogno è user1 per poter accedere ai dati tramite le procedure memorizzate che do loro, e nient'altro.

Inoltre, questo è destinato a vivere su un database SQL Azure esistente, ma sto testando prima un database fittizio locale.


Fare riferimento alla mia risposta: Come nascondere lo schema all'utente Fammi sapere se hai bisogno di ulteriori chiarimenti.
Kin Shah,

1
Questo sembra avermi reso più chiaro. Penso che il problema fosse che avevo il proprietario di Schema1 impostato su User1, anziché su dbo. Ho impostato Schema1 di proprietà dell'utente1, adattato e seguito la domanda e sono riuscito a far funzionare qualcosa. Se lo desideri, puoi proporre una risposta alla domanda. Grazie!
Julia McGuigan,

Sono contento che ti abbia aiutato.
Kin Shah,

Risposte:


17

Il concetto di base è utilizzare le autorizzazioni dello schema GRANT / DENY . È possibile gestire in modo efficiente le autorizzazioni creando un ruolo e quindi aggiungendo membri ad esso.

Di seguito è riportato un esempio che ti spiegherà in dettaglio

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

Ora prova:

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

Ora crea Stored procedure:

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

Ora concedi le autorizzazioni di esecuzione a UserA su SP di schemaB

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

Provalo .. per vedere se UserA è in grado di eseguire SP da schemaB. Questo passerà

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

Ma UserA non sarà in grado di vedere i dati da 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'.

In alternativa puoi utilizzare DATABASE ROLE e aggiungere solo utenti per una migliore gestibilità delle autorizzazioni:

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

L'istruzione seguente farà in modo che UserA sia in grado di vedere schemaA e NON schemaB. La cosa buona è che puoi semplicemente aggiungere utenti al SchemaBUsesSchemaAProcruolo e questi erediteranno tutte le autorizzazioni concesse a quel ruolo.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

Se si desidera solo consentire a UserA di eseguire SP di proprietà di SchemaB, la seguente istruzione farà il lavoro:

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

In questo modo, UserA non è in grado di vedere le tabelle di SchemaB, ma può comunque eseguire procs da SchemaB.

Di seguito spiegherà la gerarchia dei permessi :

inserisci qui la descrizione dell'immagine


2
Giusto per ribadire, è importante che entrambi gli schemi siano di proprietà dello stesso utente. Quello era il problema principale che stavo riscontrando.
Julia McGuigan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.