Nos développeurs doivent pouvoir démarrer un travail SQL Server Agent à partir de leur code .Net. Je sais que je peux appeler msdb..sp_start_job pour faire exactement cela, mais je ne veux pas donner aux comptes d'utilisateurs généraux un accès direct aux travaux d'exécution.
Ce que je voudrais faire, c'est créer une procédure stockée dans la base de données de l'application en utilisant la clause WITH EXECUTE AS pour emprunter l'identité d'un compte proxy. La procédure que nous avons est la suivante:
CREATE PROCEDURE dbo.StartAgentJob
WITH EXECUTE AS 'agentProxy'
AS
BEGIN
EXEC msdb.dbo.sp_start_job N'RunThisJob';
END
Cependant, lorsque nous l'exécutons, nous obtenons le message suivant:
The EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Des idées? Est-ce même la meilleure façon de le faire dans SQL2005?
sql-server-2005
sql
sql-server
Ed Leighton-Dick
la source
la source
Réponses:
Avez-vous mis la connexion agentProxy dans la base de données msdb et lui avez-vous donné les droits pour exécuter sp_start_job? Sinon, vous devrez activer le chaînage des autorisations de base de données pour la base de données msdb et votre base de données utilisateur.
Vous feriez probablement mieux de mettre la connexion dans la base de données msdb et de lui accorder les droits appropriés.
la source
Je suis heureux que vous ayez résolu ce problème, mais le chaînage de la propriété n'est pas la solution recommandée. Puisque vous semblez valablement préoccupé par la sécurité et la bonne granularité des droits impliqués, j'ajoute cette réponse, bien que tardive, comme référence à ce qui se passe et comment résoudre ces problèmes.
EXECUTE AS portée d'emprunt d'identité
Les clauses EXECUTE AS sont disponibles en deux versions: EXECUTE AS LOGIN et EXECUTE AS USER. EXECUTE AS LOGIN est authentifié par le serveur et est un contexte d'emprunt d'identité approuvé par l'ensemble de l'instance SQL (portée serveur):
EXECUTE AS USER est authentifié par la base de données et est un contexte d'emprunt d'identité approuvé uniquement par cette base de données (portée de la base de données):
Une procédure stockée qui a une clause EXECUTE AS créera un contexte d'emprunt d'identité de portée de base de données et, en tant que tel, ne pourra pas référencer des objets en dehors de la base de données, au cas où vous ne pourrez pas faire référence
msdb.dbo.sp_start_job
car se trouve dansmsdb
. Il existe de nombreux autres exemples disponibles, comme essayer d'accéder à un DMV de portée de serveur, essayer d'utiliser un serveur lié ou essayer de remettre un message Service Broker dans une autre base de données.Activer l'emprunt d'identité de portée de base de données pour accéder à une ressource qui ne serait normalement pas autorisée authentificateur du contexte d'emprunt d'identité doit être approuvé. Pour une usurpation d'identité à base de données, l'authentificateur est le dbo de base de données. Cela peut être réalisé par deux moyens possibles:
Ces détails sont décrits dans MSDN: Extension de l'emprunt d'identité de base de données en utilisant EXECUTE AS .
Lorsque vous avez résolu le problème via le chaînage de propriété de base de données croisée, vous avez activé le chaînage cross-db au niveau du serveur entier, ce qui est considéré comme un risque pour la sécurité. La façon la plus contrôlée et la plus fine d'obtenir le résultat souhaité est d'utiliser la signature de code:
dbo.StartAgentJob
avec ce certificatmsdb
msdb
msdb
Ces étapes garantissent que le contexte EXECUTE AS de la
dbo.StartAgentJob
procédure est désormais approuvémsdb
, car le contexte est signé par un principal disposant de l'autorisation AUTHENTICATE dansmsdb
. Cela résout la moitié du puzzle. L'autre moitié consiste à accorder réellement l'autorisation EXECUTEmsdb.dbo.sp_start_job
au contexte d'emprunt d'identité désormais fiable. Il existe plusieurs façons de procéder:agentProxy
utilisateurmsdb
et lui accorder l' autorisation d' exécution surmsdb.dbo.sp_start_job
msdb
utilisateur dérivé du certificat d'authentificateurmsdb
et accorder l'autorisation d'exécution à cet utilisateur dérivéL'option 1. est simple, mais présente un gros inconvénient: l'
agentProxy
utilisateur peut désormais exécutermsdb.dbo.sp_start_job
à sa guise, il a vraiment accès àmsdb
et a la permission d'exécution.L'option 3 est tout à fait correcte, mais je pense que c'est une surpuissance inutile.
Donc, je préfère l'option 2: accorder l'autorisation EXECUTE
msdb.dbo.sp_start_job
à l'utilisateur dérivé du certificat créé dansmsdb
.Voici le SQL correspondant:
Mon blog contient des articles couvrant ce sujet, écrits dans le contexte des procédures activées par Service Broker (car elles nécessitent une clause EXECUTE AS):
BTW, si vous essayez de tester mon script et que vous vivez dans l'hémisphère oriental ou à l'heure d'été du Royaume-Uni, lisez certainement le dernier article que j'ai lié avant de tester.
la source
Puisque vous essayez de démarrer SQL Server Agent à partir du code .NET, cela pourrait être une meilleure question pour StackOverflow?
http://www.stackoverflow.com
la source
Vérifier une instance SQL aléatoire sur le réseau SQLAgentOperatorRole ne vous donne pas directement les privilèges sp_start_job, il les hérite de SQLAgentUserRole.
Vérifiez-le en utilisant:
Exécutez cela dans MSDB et vérifiez que vous n'avez hérité d'aucun accès de refus explicite.
hth.
la source
Une façon d'y parvenir sans accorder d'autorisations supplémentaires: ne laissez pas le proc stocké démarrer le travail directement, mais laissez simplement le proc stocké retourner un peu dans une table (dans la base de données d'application); ensuite, laissez le travail s'exécuter toutes les minutes environ, vérifiez si le foret est retourné et si c'est le cas, effectuez le travail et retournez-le à nouveau. Si le travail voit que le bit n'est pas retourné, le travail se terminera simplement.
Fonctionne comme un charme, si cela ne vous dérange pas le délai (et le travail s'exécute très souvent).
la source