Eu tenho uma instância do SQL Server 2012 com alguns bancos de dados. Em um deles, criei uma visualização que seleciona tabelas em mais de um banco de dados.
Desejo que um usuário possa selecionar essa exibição, mas não deve selecionar suas tabelas. A visualização foi criada exatamente porque o usuário não pode selecionar as tabelas.
Eu li /programming/368414/grant-select-on-a-view-not-base-table e http://msdn.microsoft.com/en-us/library/ms188676. aspx e ainda não está funcionando.
Se eu fizer um GRANT SELECT TABLE TO USER
em todas as tabelas, o usuário poderá selecionar a visualização. Mas se eu revogar alguma tabela, ela falhará.
Esse deve ser um procedimento fácil, mas estou tendo problemas para fazê-lo funcionar. Já vi isso acontecer antes (o proprietário de uma instância me deu acesso a uma exibição e não o fez a suas tabelas), mas não consigo fazê-lo ou encontrar alguém que saiba como.
Alguém poderia me fornecer um tutorial sobre como fazê-lo, ou um exemplo de código?
Quando o usuário SELECTs
a visualização, recebo a mensagem:
A permissão SELECT foi negada no objeto
<TABLE>
, banco de dados<DB>
, esquemadbo
.
Se eu conceder a seleção a essa tabela, a mensagem de erro altera o nome da tabela para outra tabela que a exibição lê.
fonte
Respostas:
Se você deseja que os usuários selecionem a partir da visualização, por que você está concedendo à tabela? Por "revogar", você quer dizer revogar / negar explicitamente? Negar substituirá a concessão, portanto, o problema é seu ... você deve conseguir isso adicionando concessão à exibição e não fazendo nada nas tabelas.
Aqui está um exemplo rápido em
SELECT
que não foi concedido explicitamente na tabela, mas foi exibido. O usuário pode selecionar na visualização, mas não na tabela.Observe que isso pressupõe
foo
que não foram concedidos privilégios elevados por meio de permissões explícitas no esquema ou banco de dados, ou por meio de associação de função ou grupo.Como você está usando tabelas em vários bancos de dados (desculpe, eu perdi o final da primeira frase inicialmente), você também pode precisar de concessões explícitas nas tabelas no banco de dados em que a exibição não existe. Para evitar conceder seleção às tabelas, você pode criar uma visualização em cada banco de dados e depois ingressar nas visualizações.
Crie dois bancos de dados e um logon:
No banco de dados
d1
, crie um usuário e crie uma tabela e uma visualização simples nessa tabela. Conceda a seleção ao usuário apenas na visualização:Agora, no segundo banco de dados, crie o usuário e crie outra tabela e uma exibição que une essa tabela à exibição
d1
. Conceda a seleção apenas para a visualização.Agora inicie uma nova janela de consulta e altere as credenciais para o logon
blat
(EXECUTE AS
não funciona aqui). Em seguida, execute o seguinte no contexto de qualquer banco de dados e deve funcionar bem:Ambos devem gerar erros de mensagem 229:
Resultados:
fonte
Resposta do wiki da comunidade adicionada originalmente à pergunta por seu autor:
Isto é o que eu fiz:
SELECT
Acesso concedido ao usuário nessa visualização e NÃO a nenhuma de suas tabelas. O usuário conseguiu consultar a visualização e não as tabelas.SELECT
Acesso concedido ao usuário nesta segunda exibição e também NÃO a nenhuma tabela. O usuário conseguiu consultar esta visualização final e ver os dados.Eu acho estranho uma visão ser capaz de consultar tabelas em seu banco de dados que o usuário não tem acesso direto, mas é incapaz de fazê-lo em tabelas de outro banco de dados. Pelo menos funcionou.
fonte
Se você ativar
Cross database ownership chaining
o servidor, as visualizações cruzadas do banco de dados funcionarão bem.https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabled-cross-database-access-in-sql-server
cuide dos riscos
fonte