Em uma instância do SQL Server 2012 SP2 Standard Edition, tenho um usuário no banco de dados A que precisa ser capaz de executar procedimentos armazenados no esquema foo dentro desse banco de dados. Eles não devem ser capazes de fazer mais nada. Por exemplo, eles não devem ser capazes de SELECT diretamente de qualquer visão ou tabela em qualquer banco de dados.
As stored procedures SELECT das tabelas nos bancos de dados A e B. Eu criei as procedures WITH EXEC AS OWNER. O banco de dados A pertence a sa, que tem a função sysadmin e, portanto, deve ter acesso a ambos os bancos de dados. Eu corri isso:
USE [master]
GO
CREATE LOGIN [foo] WITH PASSWORD=N'foo', DEFAULT_DATABASE=[A]
GO
USE [A]
GO
CREATE USER [foo] FOR LOGIN [foo]
ALTER ROLE [db_executor] ADD MEMBER [foo];
GO
GRANT EXECUTE ON SCHEMA :: [Bar] TO [foo];
Eu então conectei como [foo] e executei o procedimento, mas recebi o erro:
Msg 916, Nível 14, Estado 1, Procedimento GetReport, Linha 10 O servidor principal "sa" não pode acessar o banco de dados "A" no contexto de segurança atual.
Definir TRUSTWORTHY ON parece abrir as coisas muito mais do que é aceitável. Existe outra solução?
Estou relutante em postar isso como uma resposta, porque não tenho um exemplo tangível para postar com código, mas indiquei a Mark o excelente artigo de Erland Sommarskog, Giving Permissions through Stored Procedures , que tem uma seção sobre Signing Procedures with Certificates .
A assinatura de certificado parece ser a abordagem certa para forçar o acesso aos dados por meio de um procedimento sem abrir todos os tipos de outras falhas de segurança, o que pode acontecer com o encadeamento de propriedade, usando
TRUSTWORTHY
, elevando o usuário a uma função superior ou concedendo-lhes acesso direto às tabelas (e, assim, dando a eles uma rota para contornar seus procedimentos). Vou simular um exemplo aqui conforme o tempo permitir (não será hoje, infelizmente).