Exécution d'une procédure stockée qui accède à une autre instance SQL

8

Je m'excuse si cette question répète une autre déjà posée. J'ai cherché pendant des heures et je n'ai pas trouvé celui qui correspond à ma situation.

Résultat souhaité

Un utilisateur utilisant l'authentification SQL a des autorisations d'exécution sur Database1 sur Server1 (instance par défaut) et c'est tout. L'utilisateur exécute une procédure stockée qui, dans le cadre de son processus, accède à la base de données 2 sur Server1 \ Instance2. Je voudrais que ce soit sûr et simple (les deux sont importants).

Plus d'informations

Mes informations d'identification Windows ont accès aux deux instances (qui se trouvent sur le même serveur). Par conséquent, je peux exécuter la procédure stockée sous ma connexion sans difficulté. Cependant, je ne veux pas donner à l'utilisateur mon niveau d'accès. J'ai également besoin d'utiliser une connexion SQL car l'utilisateur ne sera pas sur le domaine.

Ce que j'aimerais, c'est donner à la procédure stockée mon niveau d'accès juste pour cette procédure. Étant donné que je suis un administrateur système, cela donnerait à l'utilisateur tout ce dont il avait besoin pour cette procédure. Si je réussissais à le faire, je créerais probablement un compte juste à cette fin au lieu d'utiliser le mien, mais dans les deux cas, ce serait sûr car je contrôle ce que fait le proc stocké.

J'ai essayé de mettre l'instruction "WITH EXECUTE AS" dans mon proc stocké mais je n'ai pas pu l'obtenir pour prendre mes informations de connexion Windows. Lorsque je le mettais, j'obtiendrais l'erreur suivante lors de la compilation du proc stocké:

Impossible d'exécuter en tant qu'utilisateur 'domaine \ jdoe', car il n'existe pas ou vous n'avez pas d'autorisation.

L'utilisateur est administrateur système sur les deux serveurs, comme je l'ai dit, donc je ne sais pas de quoi il a besoin de plus.

J'ai examiné les éléments suivants:

  • CONFIANCE - Je préfère ne pas exposer ma base de données et cela semble effrayant
  • Serveur lié - Je ne veux pas accorder d'autorisations supplémentaires. Je ne fais pas confiance à l'autre base de données pour avoir accès à ma base de données et je ne fais pas confiance à ma base de données pour avoir accès à toutes les autres bases de données.
  • Certificats - Cela semble compliqué et difficile. À moins que je puisse trouver un moyen très simple de le faire et de le maintenir, je ne suis pas sûr que cela en vaille la peine.
  • Chaînage de propriété - Encore une fois, effrayant. Il semble que cela cause plus de problèmes de sécurité lorsque mon objectif est de prévenir les problèmes de sécurité.
  • Utilisateur en miroir - J'ai même créé le même utilisateur (SID différent évidemment) sur l'autre instance de serveur et lui ai donné le même mot de passe. Ne pas aller.

J'ai l'impression de manquer quelque chose d'évident mais je ne suis pas sûr de ce que c'est. Depuis que je me suis cogné la tête contre le mur toute la journée à ce sujet, je suis probablement trop près pour le voir. J'apprécierais beaucoup que quelqu'un ici me donne un coup de main ou me pointe dans la bonne direction. Je dirai que j'ai lu beaucoup d'articles MSDN (mon garçon, je les déteste - ils ne semblent jamais me dire ce que je veux savoir). Ce que j'aimerais vraiment, c'est un didacticiel simple et facile à suivre qui m'explique comment procéder. À part cela, même une indication générale de la direction que je dois prendre serait utile.

IAmTimCorey
la source

Réponses:

3

Essayez d'utiliser EXECUTE AS LOGIN = 'DOMAIN \ username' à la place et voyez si cela fonctionne.

mrdenny
la source
J'ai essayé cela, mais cette commande n'est pas conçue pour l'intérieur d'une procédure stockée, évidemment.
IAmTimCorey
Cela devrait très bien fonctionner dans une procédure stockée. Votre compte a-t-il sa propre connexion créée ou obtenez-vous vos droits via une adhésion à un groupe?
mrdenny
Mon compte possède sa propre connexion, qui dispose des droits d'administrateur système. Il dispose également de droits d'administrateur de domaine via l'appartenance à un groupe, ce qui devrait me donner tout ce dont j'ai besoin et il le fait lorsque je suis connecté à l'aide de mes informations d'identification Windows. Cependant, j'ai découvert deux choses. Premièrement, si j'utilise votre code ci-dessus dans l'instruction WITH d'un proc stocké, cela me donne une erreur de syntaxe. Si je le mets dans une déclaration, cela fonctionnera à l'intérieur d'une instance mais pas entre les instances.
IAmTimCorey
3

Jetez un œil à l'utilisation de EXECUTE AS+ Trustworthy. Vous pouvez le configurer où il peut être appelé dans la procédure stockée tant que l'utilisateur b a été autorisé et que les deux bases de données se font mutuellement confiance.

Ce blog doit répondre ou fournir tout ce dont vous avez besoin. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

l'utilisation de la propriété de base de données TRUSTWORTHY pour contrôler l'accès aux ressources en dehors de la portée de la base de données source

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

SoftwareCarpenter
la source
Le problème que je vois avec cela est que Trustworthy établit une relation de confiance entre les deux bases de données. Cela peut être exploité par les administrateurs système de chaque côté. Je ne veux pas ça. J'essaie de limiter les autorisations dont dispose une personne. Si je finis par donner à une autre personne encore plus de permissions, ce ne sera pas une bonne chose. Merci quand même.
IAmTimCorey
Notez ici que les propriétaires individuels ne doivent pas nécessairement être des personnes physiques, mais il peut s'agir d'une connexion générique pour chaque base de données. Vous n'êtes pas obligé d'accorder la totalité de la base de données. Si vous ne faites pas confiance aux administrateurs système de l'autre base de données, insistez sur la signature du certificat.
SoftwareCarpenter
Vous avez mentionné avoir rencontré le lien sommarskog.se/grantperm.html dans votre réponse ci-dessous. C'est le même blog que j'ai publié dans la réponse que j'ai suggérée. "Ce blog doit répondre ou fournir tout ce dont vous avez besoin. Sommarskog.se/grantperm.html#EXECAScrossdb " Peut-être étiez-vous simplement en train de re-référencer pour d'autres. Je suis d'accord que c'est un bon blog et lu. Bonne chance!
SoftwareCarpenter
Ouais, désolé d'avoir oublié de dire que le lien vient de toi. C'était une bonne ressource. Merci de votre aide.
IAmTimCorey
2

Après avoir lu longuement sur le sujet et fait un certain nombre d'expériences, je crois que je suis parvenu à une conclusion à ce sujet. L'instruction EXECUTE AS n'est pas conçue pour fonctionner entre des instances sans implications majeures sur la sécurité. Ce que j'espérais, c'était un moyen de dire à ma procédure sous quelle identité Windows je voulais exécuter, car une identité Windows peut avoir accès à plusieurs ressources sur plusieurs serveurs. Cependant, même après avoir joué avec un tas de paramètres différents, il est devenu évident que je devrais affaiblir d'autres mesures de sécurité afin de permettre à une procédure stockée de se faire passer pour moi.

Il ne semble pas y avoir beaucoup d'informations sur les procédures entre instances ou entre serveurs. J'imagine que la raison en est à cause des implications de sécurité et de performances de le faire. Cependant, je pense qu'il y a des cas où cela est important et il semble que les solutions pour le faire soient compliquées et très spécifiques au scénario. J'ai trouvé un bon article qui m'a aidé au moins à comprendre certaines de mes options. Il n'était pas axé sur l'accès inter-instances, mais il m'a donné les indices que je cherchais. Je vous encourage à le vérifier:

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

Je serais toujours intéressé par d'autres solutions à ce problème, mais ma solution en ce moment est double. Tout d'abord, si j'ai absolument besoin d'accéder à deux bases de données via une procédure stockée, je dois utiliser un identifiant Windows. J'évite cela autant que possible, cependant, car cela cause des problèmes de performances (verrouillage multi-serveur, complications réseau, incapacité à optimiser la requête, etc.) Deuxièmement, j'apporte les données de chaque base de données via des appels distincts et spécifiques à la base de données. Cela signifie que je ramène les données au client avant de les fusionner. Ce n'est pas aussi performant ou aussi propre que je le souhaiterais, mais cela semble être la solution la plus sûre.

IAmTimCorey
la source
1

Si vous devez accéder à des objets de base de données entre deux instances de serveur SQL, je recommanderais l'une des options suivantes:

  1. Créez et utilisez un serveur lié entre les deux instances avec l'autorisation appropriée pour accéder à l'objet sur l'instance de destination (distante).
  2. Utilisez SSIS et appelez le package à partir de l'instance source de SQL Server. Selon la version de SQL Server utilisée, vous pouvez disposer d'un travail de l'Agent SQL (non planifié pour s'exécuter, mais appelé par la procédure stockée) ou utiliser SSISDB pour appeler le package SSIS qui accédera à l'objet de base de données sur l'instance distante.
  3. Déplacez la logique vers la couche intermédiaire (ou côté application client)
  4. Créer un CLR pour accéder à l'objet de base de données distant Parmi ceux-ci, j'utiliserais probablement le CLR pour accéder au serveur d'instance distant et exécuter exécuter la procédure stockée. Vous devrez accorder au compte que l'instance SQL Server source s'exécute sous l'accès à l'instance SQL Server distante.
À M
la source