Nuestros desarrolladores deben poder iniciar un trabajo del Agente SQL Server desde su código .Net. Sé que puedo llamar a msdb..sp_start_job para hacer exactamente eso, pero no quiero dar a las cuentas de usuario generales acceso directo para ejecutar trabajos.
Lo que me gustaría hacer es crear un procedimiento almacenado en la base de datos de la aplicación utilizando la cláusula WITH EXECUTE AS para suplantar una cuenta proxy. El procedimiento tal como lo tenemos es:
CREATE PROCEDURE dbo.StartAgentJob
WITH EXECUTE AS 'agentProxy'
AS
BEGIN
EXEC msdb.dbo.sp_start_job N'RunThisJob';
END
Sin embargo, cuando ejecutamos esto, recibimos el siguiente mensaje:
The EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
¿Algunas ideas? ¿Es esta la mejor manera de hacer esto en SQL2005?
sql-server-2005
sql
sql-server
Ed Leighton-Dick
fuente
fuente
Respuestas:
¿Puso el inicio de sesión agentProxy en la base de datos msdb y le otorgó derechos para ejecutar sp_start_job? De lo contrario, deberá habilitar el encadenamiento de permisos de la base de datos para la base de datos msdb y su base de datos de usuario.
Probablemente sea mejor colocar el inicio de sesión en la base de datos msdb y otorgarle los derechos correctos.
fuente
Me alegro de que haya resuelto esto, pero el encadenamiento de propiedad no es la solución recomendada. Dado que parece estar válidamente preocupado por la seguridad y la granularidad adecuada de los derechos involucrados, agrego esta respuesta, aunque tarde, como referencia a lo que está sucediendo y cómo resolver estos problemas.
EJECUTAR COMO alcance de suplantación
Las cláusulas EJECUTAR COMO vienen en dos tipos: EJECUTAR COMO INICIAR SESIÓN y EJECUTAR COMO USUARIO. EJECUTAR COMO INICIAR SESIÓN está autenticado por el servidor y es un contexto de suplantación en el que confía toda la instancia de SQL (con ámbito de servidor):
EJECUTAR COMO USUARIO está autenticado por la base de datos y es un contexto de suplantación en el que solo confía esa base de datos (ámbito de base de datos):
Un procedimiento almacenado que tiene una cláusula EXECUTE AS creará un contexto de suplantación de ámbito de base de datos y, como tal, no podrá hacer referencia a objetos fuera de la base de datos, en este caso, no podrá hacer referencia
msdb.dbo.sp_start_job
porque está dentromsdb
. Hay muchos otros ejemplos disponibles, como intentar acceder al DMV de alcance de un servidor, intentar usar un servidor vinculado o intentar entregar un mensaje de Service Broker en otra base de datos.Habilitar la suplantación de una base de datos para acceder a un recurso en el que normalmente no se permitiría confiar en el autenticador del contexto de suplantación. Para una suplantación de ámbito de base de datos, el autenticador es la base de datos dbo. Esto se puede lograr de dos maneras posibles:
Estos detalles se describen en MSDN: Extensión de la suplantación de bases de datos mediante EXECUTE AS .
Cuando resolvió el problema mediante el encadenamiento de propiedad cruzada de la base de datos, habilitó el encadenamiento cruzado de base de datos en todo el nivel del servidor, lo que se considera un riesgo de seguridad. La forma más controlada y precisa para lograr el resultado deseado es usar la firma de código:
dbo.StartAgentJob
con este certificadomsdb
msdb
msdb
Estos pasos aseguran que
dbo.StartAgentJob
ahora se confíe enmsdb
el contexto EXECUTE AS del procedimiento , porque el contexto está firmado por un principal que tiene permiso AUTHENTICATEmsdb
. Esto resuelve la mitad del rompecabezas. La otra mitad es otorgar el permiso EXECUTEmsdb.dbo.sp_start_job
al contexto de suplantación ahora confiable. Hay varias formas de hacer esto:agentProxy
usuario enmsdb
y le conceda permiso para ejecutarmsdb.dbo.sp_start_job
msdb
usuario derivado del certificado de autenticaciónmsdb
y otorgar el permiso de ejecución a este usuario derivadoLa opción 1. es simple, pero tiene una gran desventaja: el
agentProxy
usuario ahora puede ejecutarlamsdb.dbo.sp_start_job
por su propia voluntad, realmente se le otorga accesomsdb
y tiene el permiso de ejecución.La opción 3 es muy correcta, pero creo que es una exageración innecesaria.
Por lo tanto, mi opción preferida es la 2: otorgar el permiso EXECUTE
msdb.dbo.sp_start_job
al usuario derivado del certificado creado enmsdb
.Aquí está el SQL correspondiente:
Mi blog tiene algunos artículos que cubren este tema, escritos en el contexto de los procedimientos activados por Service Broker (ya que requieren una cláusula EXECUTE AS):
Por cierto, si estás tratando de probar mi guión y vives en el hemisferio oriental, o en el horario de verano del Reino Unido, definitivamente lee el último artículo que vinculé antes de probar.
fuente
Como está intentando iniciar el Agente SQL Server desde el código .NET, ¿esta podría ser una mejor pregunta para StackOverflow?
http://www.stackoverflow.com
fuente
Comprobar una instancia SQL aleatoria en la red SQLAgentOperatorRole no le otorga los privilegios sp_start_job directamente, los hereda de SQLAgentUserRole.
Vuelva a verificarlo usando:
Ejecute esto en MSDB y verifique que no haya heredado ningún acceso de denegación explícito.
hth.
fuente
Una forma de lograr esto sin otorgar permisos adicionales: no permita que el proceso almacenado inicie el trabajo directamente, solo permita que el proceso almacenado se voltee un poco en una tabla (en la base de datos de la aplicación); luego, deje que el trabajo se ejecute cada minuto más o menos, verifique si el bit está volteado y, de ser así, realice el trabajo y vuelva a voltear el bit. Si el trabajo ve que el bit no se voltea, el trabajo simplemente saldrá.
Funciona a las mil maravillas, si no le importa la demora (y el trabajo se ejecuta muy a menudo).
fuente