Festlegen von Benutzerberechtigungen für verschiedene SQL Server-Schemas

15

Ich muss den Zugriff auf einen bestimmten Benutzer beschränken, er muss jedoch weiterhin in der Lage sein, die Daten in Tabellen von dbo anzuzeigen.

Ich versuche Folgendes zu tun:

  1. Das Dbo-Schema funktioniert wie gewohnt und hat Zugriff auf alles
  2. schema1 schema hat nur Zugriff auf schema1-Objekte
  3. Wenn eine Schema1-Ansicht oder eine gespeicherte Prozedur auf Daten in Tabellen zugreift, deren Eigentümer dbo ist, wird die Berechtigungskette entsprechend verkettet
  4. Benutzer1 hat Zugriff auf Schema1 und sonst nichts. außer im Fall von # 3

Folgendes habe ich versucht:

  1. Erstellen Sie einen Benutzer1, der einem Test-Login mit einem zufälligen Passwort zugeordnet ist
  2. Erstellt ein paar Tabellen im Dbo-Schema mit einigen Testdaten
  3. Erstellt ein Schema1-Schema
  4. Erstellt ein schema1.get_profiles, das aus einer Ansicht namens schema1.profiles auswählt, die auf Daten in dbo.people, dbo.taglinks und dbo.tags zugreift

Verwenden Sie jedoch die folgende Anweisung, während Sie als Benutzer1 angemeldet sind:

EXEC get_profiles 1

Ergebnisse in:

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

Ich habe versucht WITH EXECUTE AS OWNERund kann nicht verstehen, wie "Eigentumsverkettung" funktionieren soll.

Ich habe es auch versucht

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

Ich erhalte jedoch die folgende Fehlermeldung (obwohl ich ein Benutzer mit DBO-Zugriff bin):

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

Ich brauche user1, um über die gespeicherten Prozeduren, die ich gebe, auf die Daten zugreifen zu können, und sonst nichts.

Darüber hinaus soll dies möglicherweise in einer vorhandenen SQL Azure-Datenbank ausgeführt werden, aber ich teste zuerst mit einer lokalen Dummy-Datenbank.

Julia McGuigan
quelle
Siehe meine Antwort: So verbergen Sie das Schema vor dem Benutzer Lassen Sie mich wissen, wenn Sie weitere Erläuterungen benötigen.
Kin Shah
1
Dies scheint mir klarer zu werden. Ich denke, das Problem war, dass ich den Eigentümer von Schema1 auf User1 anstelle von dbo gesetzt hatte. Ich habe festgelegt, dass Schema1 dem Benutzer1 gehört, habe die Frage angepasst und befolgt, und es ist mir gelungen, dass etwas funktioniert. Sie können eine Antwort auf die Frage vorschlagen, wenn Sie möchten. Vielen Dank!
Julia McGuigan
Schön, dass es dir geholfen hat.
Kin Shah

Antworten:

17

Das Grundkonzept besteht darin, die GRANT / DENY-Schemaberechtigungen zu verwenden . Sie können Berechtigungen effizient verwalten, indem Sie eine Rolle erstellen und dieser dann Mitglieder hinzufügen.

Nachfolgend finden Sie ein Beispiel, das Sie ausführlich erklärt

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

Testen Sie jetzt:

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

Erstellen Sie nun gespeicherte Prozeduren:

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

Jetzt gewähren Sie UserA Ausführungsberechtigungen für den SP von schemaB

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

Testen Sie es, um festzustellen, ob UserA SP von SchemaB ausführen kann. Es wird vorübergehen

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

BenutzerA kann jedoch keine Daten aus SchemaB anzeigen

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

Alternativ können Sie DATABASE ROLE verwenden und Benutzer hinzufügen, um die Verwaltung der Berechtigungen zu vereinfachen:

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

Die folgende Anweisung stellt sicher, dass UserA schemaA und NOT schemaB sehen kann. Das Gute ist, dass Sie der SchemaBUsesSchemaAProcRolle einfach Benutzer hinzufügen können, die alle Berechtigungen erben, die dieser Rolle erteilt wurden.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

Wenn Sie nur zulassen möchten, dass UserA SPs ausführt, deren Eigentümer SchemaB ist, übernimmt die folgende Anweisung die Aufgabe:

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

Auf diese Weise kann BenutzerA die Tabellen von SchemaB nicht sehen, aber weiterhin Procs von SchemaB ausführen.

Nachfolgend wird die Berechtigungshierarchie erläutert :

Bildbeschreibung hier eingeben

Kin Shah
quelle
2
Um es noch einmal zu wiederholen, es ist wichtig, dass beide Schemas demselben Benutzer gehören. Das war das Hauptproblem, das ich hatte.
Julia McGuigan