Tengo una instancia de SQL Server 2012 con algunas bases de datos. En uno de ellos creé una vista, que selecciona tablas en más de una base de datos.
Quiero que un usuario pueda seleccionar esa vista, pero no debe seleccionar sus tablas. La vista se creó exactamente porque el usuario no puede seleccionar las tablas.
He leído /programming/368414/grant-select-on-a-view-not-base-table y http://msdn.microsoft.com/en-us/library/ms188676. aspx y todavía no funciona.
Si hago una GRANT SELECT TABLE TO USERa todas las tablas, el usuario puede seleccionar la vista. Pero si revoco a cualquier tabla, falla.
Este debería ser un procedimiento fácil de hacer, pero tengo problemas para que funcione. Lo he visto suceder antes (el propietario de una instancia me dio acceso a una vista y no lo hizo en sus tablas), pero no puedo hacerlo o encontrar a alguien que sepa cómo hacerlo.
¿Podría alguien proporcionarme un tutorial sobre cómo hacerlo, o un ejemplo de código?
Cuando el usuario SELECTsla ve me sale el mensaje:
El permiso SELECT fue denegado en el objeto
<TABLE>, base de datos<DB>, esquemadbo.
Si otorgo select a esa tabla, el mensaje de error cambia el nombre de la tabla a otra tabla que la vista lee.
fuente

Respuestas:
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
SELECTno 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.Tenga en cuenta que esto supone que
foono 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:
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: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.Ahora inicie una nueva ventana de consulta y cambie las credenciales para iniciar sesión
blat(EXECUTE ASno funciona aquí). Luego ejecute lo siguiente desde el contexto de cualquiera de las bases de datos, y debería funcionar bien:Ambos deberían producir errores Msg 229:
Resultados:
fuente
Respuesta wiki de la comunidad originalmente agregada a la pregunta por su autor:
Esto es lo que hice:
SELECTAcceso otorgado al usuario en esa vista, y NO a ninguna de sus tablas. El usuario pudo consultar con éxito la vista y no las tablas.SELECTAcceso otorgado al usuario en esta segunda vista, y NO a ninguna tabla. El usuario pudo consultar con éxito esta vista final y ver los datos.Creo que es extraño que una vista pueda consultar tablas en su DB que el usuario no tiene acceso directo pero no puede hacerlo en tablas de otro DB. Al menos funcionó.
fuente
Si activa
Cross database ownership chainingpara el servidor, las vistas cruzadas de la base de datos funcionarán bien.https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-cross-database-access-in-sql-server
cuenta los riesgos
fuente