Ejecutar procedimiento almacenado que accede a otra instancia de SQL


8

Pido disculpas si esta pregunta repite otra ya formulada. He buscado durante horas y no he encontrado uno que se ajuste a mi situación.

Resultado deseado

Un usuario que usa la autenticación SQL tiene permisos de ejecución para la Base de datos1 en el Servidor1 (instancia predeterminada) y eso es todo. El usuario ejecuta un procedimiento almacenado que, como parte de su proceso, accede a la Base de datos 2 en el Servidor1 \ Instancia2. Me gustaría que fuera seguro y simple (ambos son importantes).

Más información

Mis credenciales de Windows tienen acceso a ambas instancias (que están en el mismo servidor). Por lo tanto, puedo ejecutar el procedimiento almacenado en mi inicio de sesión sin dificultad. Sin embargo, no quiero darle al usuario mi nivel de acceso. También necesito usar un inicio de sesión SQL ya que el usuario no estará en el dominio.

Lo que me gustaría sería darle al procedimiento almacenado mi nivel de acceso solo para ese procedimiento. Como soy un administrador de sistemas, eso le daría al usuario todo lo que necesita para ese procedimiento. Si eso funcionara, probablemente crearía una cuenta solo para ese propósito en lugar de usar la mía, pero de cualquier manera sería seguro ya que controlo lo que hace el proceso almacenado.

Intenté poner la declaración "WITH EXECUTE AS" en mi proceso almacenado, pero no pude conseguir que tomara mi información de inicio de sesión de Windows. Cuando lo coloco, obtengo el siguiente error al compilar el proceso almacenado:

No se puede ejecutar como el usuario 'dominio \ jdoe', porque no existe o no tiene permiso.

El usuario es administrador del sistema en ambos servidores, como dije, así que no estoy seguro de qué más necesita.

He investigado lo siguiente:

  • CONFÍA - Prefiero no exponer mi base de datos y esto da miedo
  • Servidor vinculado: no quiero otorgar permisos adicionales. No confío en que la otra base de datos tenga acceso a mi base de datos y no confío en que mi base de datos tenga acceso a todas las demás bases de datos.
  • Certificados: esto parece complicado y difícil. A menos que pueda encontrar una manera muy simple de hacer esto y mantenerlo, no estoy seguro de que valga la pena.
  • Encadenamiento de propiedad - De nuevo, da miedo. Parece que esto causa más problemas de seguridad cuando mi objetivo es evitar problemas de seguridad.
  • Usuario reflejado: incluso he creado el mismo usuario (obviamente, SID diferente) en la otra instancia del servidor y le di la misma contraseña. No vayas.

Siento que me falta algo obvio, pero no estoy seguro de qué es. Dado que me he estado golpeando la cabeza contra la pared todo el día con esto, probablemente estoy demasiado cerca para verlo. Le agradecería mucho que alguien aquí pudiera echarme una mano o señalarme en la dirección correcta. Diré que he leído muchos de los artículos de MSDN (vaya que los odio, nunca parecen decirme lo que quiero saber). Lo que realmente me gustaría es un tutorial simple y fácil de seguir que me guíe a través de cómo hacer esto. Aparte de eso, incluso una indicación general de la dirección que debo seguir sería útil.

Respuestas:


3

Intente usar EXECUTE AS LOGIN = 'DOMAIN \ username' en su lugar y vea si eso funciona.


Intenté eso, pero ese comando no está diseñado para dentro de un procedimiento almacenado, evidentemente.
IAmTimCorey

Debería funcionar bien dentro de un procedimiento almacenado. ¿Su cuenta tiene su propio inicio de sesión creado o está obteniendo sus derechos a través de una membresía de grupo?
mrdenny

Mi cuenta tiene su propio inicio de sesión, que tiene derechos de administrador del sistema. También tiene derechos de administrador de dominio a través de la membresía de grupo, por lo que debería darme todo lo que necesito y lo hace cuando inicio sesión con mis credenciales de Windows. Sin embargo, descubrí dos cosas. Primero, si uso el código anterior en la instrucción WITH de un proceso almacenado, me da un error de sintaxis. Si lo pongo en una declaración, funcionará dentro de una instancia pero no entre instancias.
IAmTimCorey 01 de

3

Echa un vistazo al uso de EXECUTE AS+ Confiable. Puede configurarlo donde pueda llamarse dentro del procedimiento almacenado, siempre que el usuario b tenga acceso y las dos bases de datos confíen entre sí.

Este blog de chicos debe responder o proporcionar todo lo que necesita. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

El uso de la propiedad de la base de datos TRUSTWORTHY para controlar el acceso a recursos fuera del alcance de la base de datos fuente

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


El problema que veo con eso es que Trustworthy establece una relación de confianza entre las dos bases de datos. Esto puede ser explotado por los administradores de sistemas en cualquier lado. No quiero esto Estoy tratando de limitar los permisos que tiene una persona. Si termino dándole a otra persona aún más permisos, eso no será algo bueno. Gracias sin embargo.
IAmTimCorey 01 de

Tenga en cuenta que los propietarios individuales no tienen que ser personas físicas, pero podría ser un inicio de sesión genérico para cada base de datos. No tiene que otorgar la base de datos completa. Si no confía en los administradores del sistema en la otra base de datos, insista en la firma del certificado.
SoftwareCarpenter

Usted mencionó que encontró el enlace sommarskog.se/grantperm.html en su respuesta a continuación. Ese es el mismo blog que publiqué en la respuesta que sugerí. "Este blog de chicos debería responder o proporcionar todo lo que necesita. Sommarskog.se/grantperm.html#EXECAScrossdb " Tal vez solo estaba haciendo referencia a otros. Estoy de acuerdo en que es un buen blog y leer. ¡Buena suerte!
SoftwareCarpenter

Sí, lo siento, olvidé decir que el enlace vino de ti. Fue un buen recurso. Gracias por tu ayuda.
IAmTimCorey

2

Después de leer extensamente sobre el tema y hacer varios experimentos, creo que he llegado a una conclusión sobre este asunto. La instrucción EXECUTE AS no está diseñada para funcionar entre instancias sin mayores implicaciones de seguridad. Lo que esperaba era una forma de decirle a mi procedimiento con qué identidad de Windows quería ejecutar, ya que una identidad de Windows puede tener acceso a múltiples recursos en múltiples servidores. Sin embargo, incluso después de jugar con un montón de configuraciones diferentes, se hizo evidente que tendría que debilitar otras medidas de seguridad para permitir que un procedimiento almacenado se haga pasar por mí.

Parece que no hay mucha información sobre procedimientos de instancias cruzadas o servidores cruzados. Me imagino que la razón de esto se debe a las implicaciones de seguridad y rendimiento de hacerlo. Sin embargo, creo que hay casos en los que es importante y parece que las soluciones para hacerlo son complicadas y muy específicas de cada escenario. Encontré un buen artículo que me ayudó al menos a comprender algunas de mis opciones. No se centró en el acceso de instancia cruzada, pero me dio las pistas que estaba buscando. Te animo a echarle un vistazo:

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

Todavía estaría interesado en otras soluciones a este problema, pero mi solución en este momento es doble. Primero, si realmente necesito acceder a dos bases de datos a través de un procedimiento almacenado, tengo que usar un inicio de sesión de Windows. Sin embargo, evito esto siempre que sea posible, ya que causa problemas de rendimiento (bloqueo de varios servidores, complicaciones de la red, incapacidad para optimizar la consulta, etc.). Segundo, llevo los datos de cada base de datos a través de llamadas separadas específicas de la base de datos. Eso significa que devuelvo los datos al cliente antes de fusionarlos. No es tan eficiente ni tan limpio como me gustaría, pero parece ser la solución más segura.


1

Si necesita acceder a los objetos de la base de datos entre dos instancias del servidor SQL, le recomendaría uno de los siguientes:

  1. Cree y use un servidor vinculado entre las dos instancias con el permiso apropiado para acceder al objeto en la instancia (remota) de destino.
  2. Use SSIS e invoque el paquete desde la instancia de origen de SQL Server. Dependiendo de la versión de SQL Server utilizada, puede tener un trabajo de Agente SQL (no programado para ejecutarse, pero llamado por el procedimiento almacenado) o usar el SSISDB para invocar el paquete SSIS que accederá al objeto de la base de datos en la instancia remota.
  3. Mueva la lógica a la capa intermedia (o al lado de la aplicación del cliente)
  4. Cree un CLR para acceder al objeto de la base de datos remota De estos probablemente usaría el CLR para acceder al servidor de instancia remota y ejecutar el procedimiento almacenado. Deberá otorgar a la cuenta que la instancia de SQL Server de origen se ejecuta con acceso a la instancia remota de SQL Server.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.