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 USER
a 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 SELECTs
la 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
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.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:
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 AS
no 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:
SELECT
Acceso 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.SELECT
Acceso 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 chaining
para 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