Nossos desenvolvedores precisam poder iniciar um trabalho do SQL Server Agent a partir do código .Net. Eu sei que posso chamar msdb..sp_start_job para fazer exatamente isso, mas não quero dar acesso direto às contas de usuário em geral para executar tarefas.
O que eu gostaria de fazer é criar um procedimento armazenado no banco de dados do aplicativo usando a cláusula WITH EXECUTE AS para representar uma conta proxy. O procedimento como o temos é:
CREATE PROCEDURE dbo.StartAgentJob
WITH EXECUTE AS 'agentProxy'
AS
BEGIN
EXEC msdb.dbo.sp_start_job N'RunThisJob';
END
Porém, quando executamos isso, recebemos a seguinte mensagem:
The EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Alguma ideia? Essa é a melhor maneira de fazer isso no SQL2005?
sql-server-2005
sql
sql-server
Ed Leighton-Dick
fonte
fonte
Respostas:
Você colocou o logon agentProxy no banco de dados msdb e concedeu direitos para executar sp_start_job? Caso contrário, será necessário ativar o encadeamento de permissões do banco de dados para o banco de dados msdb e o banco de dados do usuário.
Provavelmente, é melhor colocar o logon no banco de dados msdb e conceder os direitos corretos.
fonte
Estou feliz que você tenha resolvido isso, mas o encadeamento de propriedade não é a solução recomendada. Como você parece validamente preocupado com a segurança e a granularidade adequada dos direitos envolvidos, estou adicionando esta resposta, embora atrasada, como uma referência ao que está acontecendo e como resolver esses problemas.
EXECUTAR COMO escopo de representação
As cláusulas EXECUTE AS têm dois tipos: EXECUTE AS LOGIN e EXECUTE AS USUÁRIO. O EXECUTE AS LOGIN é autenticado pelo servidor e é um contexto de representação confiável para toda a instância SQL (com escopo no servidor):
EXECUTE AS USER é autenticado pelo banco de dados e é um contexto de representação confiável apenas por esse banco de dados (com escopo no banco de dados):
Um procedimento armazenado que possui uma cláusula EXECUTE AS criará um contexto de representação no escopo do banco de dados e, como tal, não poderá fazer referência a objetos fora do banco de dados, caso em que você não poderá fazer referência
msdb.dbo.sp_start_job
porque está dentromsdb
. Existem muitos outros exemplos disponíveis, como tentar acessar uma DMV do escopo do servidor, tentar usar um servidor vinculado ou tentar entregar uma mensagem do Service Broker em outro banco de dados.A habilitação de uma representação no escopo do banco de dados para acessar um recurso que normalmente não seria permitido no qual o autenticador do contexto de representação deve ser confiável. Para uma representação no escopo do banco de dados, o autenticador é o dbo do banco de dados. Isso pode ser alcançado por dois meios possíveis:
Esses detalhes são descritos no MSDN: Estendendo a representação de banco de dados usando o EXECUTE AS .
Quando você resolveu o problema por meio do encadeamento de propriedade entre bancos de dados, ativou o encadeamento entre bancos de dados em todo o nível do servidor, o que é considerado um risco de segurança. A maneira mais controlada e refinada de obter o resultado desejado é usar a assinatura de código:
dbo.StartAgentJob
com este certificadomsdb
msdb
msdb
Essas etapas garantem que o contexto EXECUTE AS do
dbo.StartAgentJob
procedimento agora seja confiávelmsdb
, porque o contexto é assinado por uma entidade com permissão AUTHENTICATEmsdb
. Isso resolve metade do quebra-cabeça. A outra metade é realmente conceder a permissão EXECUTEmsdb.dbo.sp_start_job
para o contexto de representação agora confiável. Existem várias maneiras de como isso pode ser feito:agentProxy
usuário representadomsdb
e conceder a ele permissão de execução emmsdb.dbo.sp_start_job
msdb
usuário derivado do certificado de autenticadormsdb
e conceda a permissão de execução a esse usuário derivadoA opção 1. é simples, mas tem uma grande desvantagem: o
agentProxy
usuário agora pode executar o quemsdb.dbo.sp_start_job
quiser, ele realmente tem acessomsdb
e permissão de execução.A opção 3 está positivamente correta, mas acho que é um exagero desnecessário.
Portanto, minha preferida é a Opção 2: conceda a permissão EXECUTE
msdb.dbo.sp_start_job
ao usuário derivado do certificado criado emmsdb
.Aqui está o SQL correspondente:
Meu blog possui alguns artigos que abordam esse tópico, escritos no contexto dos procedimentos ativados pelo Service Broker (uma vez que exigem uma cláusula EXECUTE AS):
BTW, se você está tentando testar meu roteiro e mora no hemisfério leste ou no horário de verão do Reino Unido, leia definitivamente o último artigo que vinculei antes de testar.
fonte
Como você está tentando iniciar o SQL Server Agent a partir do código .NET, essa pode ser uma pergunta melhor para o StackOverflow?
http://www.stackoverflow.com
fonte
A verificação de uma instância SQL aleatória na rede SQLAgentOperatorRole não fornece privilégios sp_start_job diretamente, ela os herda de SQLAgentUserRole.
Verifique-o usando:
Execute isso no MSDB e verifique se você não herdou nenhum acesso negado explícito.
hth.
fonte
Uma maneira de conseguir isso sem conceder permissões adicionais: não permita que o processo armazenado inicie o trabalho diretamente, mas permita que o processo armazenado inverta um pouco em uma tabela (no banco de dados do aplicativo); então, deixe o trabalho ser executado a cada minuto, verifique se o bit está invertido e, se estiver, execute o trabalho e inverta o bit novamente. Se o trabalho perceber que o bit não está invertido, o trabalho será encerrado.
Funciona como um encanto, se você não se importa com o atraso (e o trabalho sendo executado com muita frequência).
fonte