Wenn Sie möchten, dass Benutzer aus der Ansicht auswählen, warum gewähren Sie der Tabelle? Mit "widerrufen" meinen Sie explizit widerrufen / verweigern? Verweigern überschreibt die Gewährung, sodass Ihr Problem vorliegt. Sie sollten dies erreichen können, indem Sie der Ansicht eine Bewilligung hinzufügen und in den Tabellen nichts tun.
Hier ist ein kurzes Beispiel, in dem SELECT
nicht explizit für die Tabelle, sondern für die Ansicht gewährt wurde. Der Benutzer kann aus der Ansicht auswählen, jedoch nicht aus der Tabelle.
CREATE USER foo WITHOUT LOGIN;
GO
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT);
GO
CREATE VIEW dbo.v
AS
SELECT a.id FROM a INNER JOIN b ON a.id = b.id;
GO
GRANT SELECT ON dbo.v TO foo;
GO
EXECUTE AS USER = N'foo';
GO
-- works:
SELECT id FROM dbo.v;
GO
-- Msg 229, SELECT denied:
SELECT id FROM dbo.a;
GO
REVERT;
Beachten Sie, dass davon ausgegangen foo
wird, dass keine erhöhten Berechtigungen durch explizite Berechtigungen für das Schema oder die Datenbank oder durch Rollen- oder Gruppenmitgliedschaft gewährt wurden.
Da Sie Tabellen in mehreren Datenbanken verwenden (es tut mir leid, dass ich das Ende dieses ersten Satzes anfangs verpasst habe), benötigen Sie möglicherweise auch explizite Berechtigungen für die Tabelle (n) in der Datenbank, in der die Ansicht nicht vorhanden ist. Um zu vermeiden, dass den Tabellen eine Auswahl zugewiesen wird, können Sie in jeder Datenbank eine Ansicht erstellen und dann die Ansichten verbinden.
Erstellen Sie zwei Datenbanken und ein Login:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
d1
Erstellen Sie in der Datenbank einen Benutzer und erstellen Sie dann eine Tabelle und eine einfache Ansicht für diese Tabelle. Gewähren Sie dem Benutzer nur eine Auswahl für die Ansicht:
USE d1;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t1(id INT);
GO
CREATE VIEW dbo.v1
AS
SELECT id FROM dbo.t1;
GO
GRANT SELECT ON dbo.v1 TO blat;
GO
Erstellen Sie nun in der zweiten Datenbank den Benutzer und anschließend eine weitere Tabelle und eine Ansicht, die diese Tabelle mit der Ansicht in verbindet d1
. Gewähren Sie Auswahl nur für die Ansicht.
USE d2;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t2(id INT);
GO
CREATE VIEW dbo.v2
AS
SELECT v1.id FROM dbo.t2
INNER JOIN d1.dbo.v1 AS v1
ON t2.id = v1.id;
GO
GRANT SELECT ON dbo.v2 TO blat;
GO
Starten Sie nun ein neues Abfragefenster und ändern Sie die Anmeldeinformationen für die Anmeldung blat
( EXECUTE AS
funktioniert hier nicht). Führen Sie dann im Kontext einer der beiden Datenbanken Folgendes aus, und es sollte einwandfrei funktionieren:
SELECT id FROM d1.dbo.v2;
Diese sollten beide Msg 229-Fehler ergeben:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Ergebnisse:
Meldung 229, Ebene 14, Status 5, Zeile 1
Die SELECT-Berechtigung wurde für das Objekt 't1', Datenbank 'd1', Schema 'dbo' verweigert.
Meldung 229, Ebene 14, Status 5, Zeile 3
Die SELECT-Berechtigung wurde für das Objekt 't2', Datenbank 'd2', Schema 'dbo' verweigert.