Jeśli chcesz, aby użytkownicy wybierali z widoku, dlaczego udzielasz tabeli? Przez „odwołanie” masz na myśli wprost odwołanie / odrzucenie? Odmowa zastąpi grant, więc jest twój problem ... powinieneś być w stanie to zrobić, dodając grant do widoku i nie robiąc nic w żaden sposób na stołach.
Oto szybki przykład, w którym SELECT
nie podano wyraźnie tabeli, ale widok. Użytkownik może wybrać z widoku, ale nie z tabeli.
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;
Należy pamiętać, że zakłada to, że foo
nie przyznano podwyższonych uprawnień poprzez wyraźne uprawnienia do schematu lub bazy danych, ani poprzez członkostwo w roli lub grupie.
Ponieważ używasz tabel w wielu bazach danych (przepraszam, początkowo brakowało mi końca pierwszego zdania), możesz również potrzebować wyraźnych przydziałów dla tabel w bazie danych, w których widok nie istnieje. Aby uniknąć przyznawania wyboru tabelom, możesz utworzyć widok w każdej bazie danych, a następnie dołączyć widoki.
Utwórz dwie bazy danych i login:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
W bazie danych d1
utwórz użytkownika, a następnie utwórz tabelę i prosty widok dla tej tabeli. Przyznaj użytkownikowi wybór tylko w stosunku do widoku:
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
Teraz w drugiej bazie danych utwórz użytkownika, a następnie utwórz kolejną tabelę i widok, który łączy tę tabelę z widokiem w d1
. Przyznaj zaznacz tylko do widoku.
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
Teraz uruchom nowe okno zapytania i zmień dane logowania do logowania blat
( EXECUTE AS
tutaj nie działa). Następnie uruchom następujące polecenie w kontekście dowolnej bazy danych i powinno działać dobrze:
SELECT id FROM d1.dbo.v2;
Oba powinny przynieść błędy Msg 229:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Wyniki:
Msg 229, poziom 14, stan 5, wiersz 1
Odmówiono uprawnienia SELECT do obiektu „t1”, bazy danych „d1”, schematu „dbo”.
Msg 229, poziom 14, stan 5, wiersz 3
Odmówiono uprawnienia SELECT do obiektu „t2”, bazy danych „d2”, schematu „dbo”.