Si desea que los usuarios seleccionen desde la vista, ¿por qué está otorgando a la tabla? Por "revocar", ¿quiere decir explícitamente revocar / negar? Denegar anulará la concesión, por lo que está su problema ... debería poder lograr esto agregando concesión a la vista y no haciendo nada de ninguna manera en las tablas.
Aquí hay un ejemplo rápido en el que SELECT
no se ha otorgado explícitamente en la tabla, pero sí en la vista. El usuario puede seleccionar desde la vista pero no desde la tabla.
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;
Tenga en cuenta que esto supone que foo
no se le han otorgado privilegios elevados a través de permisos explícitos en el esquema o la base de datos, o mediante la pertenencia a roles o grupos.
Como está utilizando tablas en varias bases de datos (lo siento, me perdí el final de esa primera oración inicialmente), también puede necesitar concesiones explícitas en las tablas en la base de datos donde la vista no existe. Para evitar otorgar selección a las tablas, puede crear una vista en cada base de datos y luego unir las vistas.
Cree dos bases de datos y un inicio de sesión:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
En la base de datos d1
, cree un usuario, luego cree una tabla y una vista simple contra esa tabla. Otorgue selección al usuario solo contra la vista:
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
Ahora, en la segunda base de datos, cree el usuario, luego cree otra tabla y una vista que una esa tabla a la vista d1
. Otorgue selección solo a la vista.
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
Ahora inicie una nueva ventana de consulta y cambie las credenciales para iniciar sesión blat
( EXECUTE AS
no funciona aquí). Luego ejecute lo siguiente desde el contexto de cualquiera de las bases de datos, y debería funcionar bien:
SELECT id FROM d1.dbo.v2;
Ambos deberían producir errores Msg 229:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Resultados:
Mensaje 229, Nivel 14, Estado 5, Línea 1
El permiso SELECT fue denegado en el objeto 't1', base de datos 'd1', esquema 'dbo'.
Mensaje 229, Nivel 14, Estado 5, Línea 3
El permiso SELECT fue denegado en el objeto 't2', base de datos 'd2', esquema 'dbo'.