Executando procedimento armazenado que acessa outra instância SQL

8

Peço desculpas se esta pergunta repete outra já feita. Eu procurei por horas e não encontrei um que se encaixa na minha situação.

Resultado desejado

Um usuário que usa autenticação SQL possui permissões de execução no Banco de Dados1 no Servidor1 (instância padrão) e é isso. O usuário executa um procedimento armazenado que, como parte de seu processo, acessa o Banco de Dados 2 em Server1 \ Instance2. Eu gostaria que fosse seguro e simples (ambos são importantes).

Mais informações

Minhas credenciais do Windows têm acesso às duas instâncias (que estão no mesmo servidor). Portanto, eu posso executar o procedimento armazenado no meu login sem dificuldade. No entanto, não quero dar ao usuário meu nível de acesso. Também preciso usar um logon SQL, pois o usuário não estará no domínio.

O que eu gostaria seria fornecer ao procedimento armazenado meu nível de acesso apenas para esse procedimento. Como eu sou um administrador de sistema, isso daria ao usuário tudo o que eles precisavam para esse procedimento. Se eu conseguisse isso funcionar, provavelmente criaria uma conta apenas para esse fim, em vez de usar a minha, mas de qualquer forma seria seguro, pois eu controlava o que o proc armazenado faz.

Tentei colocar a instrução "WITH EXECUTE AS" no meu processo armazenado, mas não consegui obter as informações de login do Windows. Quando eu o colocava, recebia o seguinte erro ao compilar o processo armazenado:

Não é possível executar como o usuário 'domínio \ jdoe', porque ele não existe ou você não tem permissão.

O usuário é sysadmin nos dois servidores, como eu disse, então não tenho certeza do que mais ele precisa.

Analisei o seguinte:

  • CONFIADO - Prefiro não expor meu banco de dados e isso parece assustador
  • Servidor vinculado - não quero dar permissões extras. Não confio no outro banco de dados para ter acesso ao meu banco de dados e não confio no meu banco de dados para ter acesso a todos os outros bancos de dados.
  • Certificados - isso parece complicado e difícil. A menos que eu possa encontrar uma maneira muito simples de fazer isso e mantê-lo, não tenho certeza se vale a pena.
  • Encadeamento de propriedade - Novamente, assustador. Parece que isso causa mais problemas de segurança quando meu objetivo é evitar problemas de segurança.
  • Usuário espelhado - eu até criei o mesmo usuário (SID diferente, obviamente) na outra instância do servidor e dei a mesma senha. Não vá.

Sinto que estou perdendo algo óbvio, mas não tenho certeza do que é. Desde que eu bati minha cabeça contra a parede o dia todo com isso, provavelmente estou muito perto para vê-lo. Eu apreciaria muito se alguém aqui pudesse me dar uma mão ou me apontar na direção certa. Eu direi que li muitos artigos do MSDN (cara, eu os odeio - eles nunca parecem me dizer o que eu quero saber). O que eu realmente gostaria é de um tutorial simples e fácil de seguir, que me mostra como fazer isso. Além disso, mesmo uma indicação geral da direção que preciso seguir seria útil.

IAmTimCorey
fonte

Respostas:

3

Tente usar EXECUTE AS LOGIN = 'DOMÍNIO \ nome de usuário' e verifique se isso funciona.

Mrdenny
fonte
Eu tentei isso, mas esse comando não foi projetado para dentro de um procedimento armazenado, evidentemente.
IAmTimCorey 28/01
Deve funcionar bem dentro de um procedimento armazenado. Sua conta tem seu próprio login criado ou você está obtendo seus direitos por meio de uma associação de grupo?
mrdenny
Minha conta tem seu próprio login, que possui direitos de administrador de sistema. Ele também possui direitos de Administrador de Domínio por meio de associação ao grupo, de modo que deve me fornecer tudo o que preciso e quando faço logon usando minhas credenciais do Windows. No entanto, eu descobri duas coisas. Primeiro, se eu usar o código acima na instrução WITH de um processo armazenado, isso me dará um erro de sintaxe. Se eu colocá-lo em uma declaração, ele funcionará dentro de uma instância, mas não entre instâncias.
IAmTimCorey
3

Veja como usar EXECUTE AS+ Confiável. Você pode configurá-lo onde pode ser chamado no procedimento armazenado, desde que o usuário b tenha acesso e os dois bancos de dados confiem um no outro.

Este blog pessoal deve responder ou fornecer tudo o que você precisa. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

o uso da propriedade do banco de dados TRUSTWORTHY para controlar o acesso a recursos fora do escopo do banco de dados de origem

http://msdn.microsoft.com/en-us/library/ms188304%28v=sql.90%29.aspx

SoftwareCarpenter
fonte
O problema que vejo é que o Trustworthy estabelece uma relação de confiança entre os dois bancos de dados. Isso pode ser explorado pelos administradores de sistemas de ambos os lados. Eu não quero isso Estou tentando limitar as permissões de uma pessoa. Se eu acabar dando a outra pessoa ainda mais permissões, isso não será uma coisa boa. Obrigado embora.
IAmTimCorey
Observe aqui que os proprietários individuais não precisam ser pessoas físicas, mas pode ser um login genérico para cada banco de dados. Você não precisa conceder todo o banco de dados. Se você não confia nos administradores do sistema no outro banco de dados, insista na assinatura do certificado.
SoftwareCarpenter
Você mencionou que encontrou o link sommarskog.se/grantperm.html na sua resposta abaixo. Esse é o mesmo blog que eu postei na resposta que sugeri. "Este blog de pessoal deve responder ou fornecer tudo o que você precisa. Sommarskog.se/grantperm.html#EXECAScrossdb " Talvez você estivesse apenas se referindo novamente a outras pessoas. Concordo que é um bom blog e lido. Boa sorte!
SoftwareCarpenter
Sim, desculpe, esqueci de dizer que o link veio de você. Foi um bom recurso. Obrigado pela ajuda.
IAmTimCorey 02/02/12
2

Depois de ler bastante sobre o assunto e fazer várias experiências, acredito que cheguei a uma conclusão sobre esse assunto. A instrução EXECUTE AS não foi projetada para funcionar entre instâncias sem grandes implicações de segurança. O que eu esperava era uma maneira de dizer ao meu procedimento em que identidade do Windows eu queria executar, já que uma identidade do Windows pode ter acesso a vários recursos em vários servidores. No entanto, mesmo depois de brincar com várias configurações diferentes, ficou claro que eu precisaria enfraquecer outras medidas de segurança para permitir que um procedimento armazenado me personificasse.

Parece não haver muita informação disponível sobre procedimentos entre instâncias ou entre servidores. Eu imagino que a razão disso seja devido às implicações de segurança e desempenho de fazer isso. No entanto, acredito que há casos em que isso é importante e parece que as soluções para isso são complicadas e muito específicas do cenário. Me deparei com um bom artigo que me ajudou a entender pelo menos algumas das minhas opções. Não estava focado no acesso entre instâncias, mas me deu as pistas que estava procurando. Gostaria de encorajá-lo a verificar:

http://www.sommarskog.se/grantperm.html

Eu ainda estaria interessado em outras soluções para esse problema, mas minha solução agora é dupla. Primeiro, se eu absolutamente precisar acessar dois bancos de dados por meio de um procedimento armazenado, tenho que usar um logon do Windows. Porém, evito isso sempre que possível, pois causa problemas de desempenho (bloqueio de vários servidores, complicações de rede, incapacidade de otimizar a consulta etc.) Segundo, trago os dados de cada banco de dados por meio de chamadas separadas e específicas do banco de dados. Isso significa que eu trago os dados de volta ao cliente antes de mesclá-los. Não é tão eficiente ou limpo quanto eu gostaria, mas parece ser a solução mais segura.

IAmTimCorey
fonte
1

Se você precisar acessar objetos de banco de dados entre duas Instâncias do servidor SQL, recomendo um dos seguintes:

  1. Crie e use um servidor vinculado entre as duas instâncias com a permissão apropriada para acessar o objeto na instância de destino (remota).
  2. Use o SSIS e chame o pacote da instância de origem do SQL Server. Dependendo da versão do SQL Server usada, você pode ter um trabalho do SQL Agent (não agendado para execução, mas chamado pelo procedimento armazenado) ou usar o SSISDB para chamar o pacote SSIS que acessará o objeto de banco de dados na instância remota.
  3. Mova a lógica para a camada intermediária (ou o lado do aplicativo cliente)
  4. Criar um CLR para acessar o objeto de banco de dados remoto Desses, eu provavelmente usaria o CLR para acessar o servidor de instância remota e executar o procedimento armazenado. Você precisará conceder à conta que a Instância do SQL Server de Origem é executada sob acesso à Instância Remota do SQL Server.
Tom
fonte