Esecuzione della stored procedure che accede a un'altra istanza SQL


8

Mi scuso se questa domanda ripete un'altra già posta. Ho cercato per ore e non ne ho trovato uno adatto alla mia situazione.

Risultato desiderato

Un utente che utilizza l'autenticazione SQL ha le autorizzazioni per Database1 su Server1 (istanza predefinita) e basta. L'utente esegue una procedura memorizzata che, come parte del suo processo, accede al Database 2 su Server1 \ Instance2. Vorrei che fosse sicuro e semplice (entrambi sono importanti).

Ulteriori informazioni

Le mie credenziali di Windows hanno accesso ad entrambe le istanze (che si trovano sullo stesso server). Pertanto, posso eseguire la procedura memorizzata con il mio login senza difficoltà. Tuttavia, non voglio fornire all'utente il mio livello di accesso. Devo anche usare un login SQL poiché l'utente non sarà nel dominio.

Quello che vorrei sarebbe dare alla procedura memorizzata il mio livello di accesso solo per quella procedura. Dato che sono un amministratore di sistema, ciò darebbe all'utente tutto ciò di cui aveva bisogno per quella procedura. Se dovessi farlo funzionare, probabilmente creerei un account solo per quello scopo invece di usare il mio, ma in entrambi i casi sarebbe sicuro poiché controllo ciò che fa il proc memorizzato.

Ho provato a inserire l'istruzione "WITH EXECUTE AS" nel mio proc memorizzato ma non sono riuscito a ottenere le informazioni di accesso a Windows. Quando lo inserisco, ottengo il seguente errore quando compilo il proc memorizzato:

Impossibile eseguire come utente "dominio \ jdoe" perché non esiste o non si dispone dell'autorizzazione.

L'utente è amministratore di sistema su entrambi i server, come ho detto, quindi non sono sicuro di cosa abbia bisogno.

Ho esaminato quanto segue:

  • AFFIDABILE - Preferirei non esporre il mio database e questo sembra spaventoso
  • Server collegato: non desidero concedere autorizzazioni aggiuntive. Non mi fido che l'altro database abbia accesso al mio database e non mi fido che il mio database abbia accesso a tutto l'altro database.
  • Certificati: questo sembra complicato e difficile. A meno che non riesca a trovare un modo molto semplice per farlo e mantenerlo, non sono sicuro che valga la pena.
  • Concatenamento della proprietà - Ancora una volta, spaventoso. Sembra che questo causi più problemi di sicurezza quando il mio obiettivo è prevenire problemi di sicurezza.
  • Utente con mirroring - Ho persino creato lo stesso utente (ovviamente SID diverso) sull'altra istanza del server e gli ho dato la stessa password. Non andare.

Sento che mi manca qualcosa di ovvio, ma non sono sicuro di cosa si tratti. Da quando ho sbattuto la testa contro il muro tutto il giorno, probabilmente sono troppo vicino per vederlo. Lo apprezzerei molto se qualcuno qui potesse darmi una mano o indicarmi la giusta direzione. Dirò di aver letto molti articoli di MSDN (ragazzo, li odio - non sembrano mai dirmi quello che voglio sapere). Quello che mi piacerebbe davvero è un tutorial semplice e facile da seguire che mi guida attraverso come fare questo. A parte questo, sarebbe utile anche un'indicazione generale della direzione da seguire.

Risposte:


3

Prova invece a utilizzare EXECUTE AS LOGIN = 'DOMAIN \ username' e verifica se funziona.


L'ho provato ma quel comando non è progettato per una stored procedure, evidentemente.
IAmTimCorey,

Dovrebbe funzionare bene all'interno di una procedura memorizzata. Il tuo account ha il proprio login creato o stai ottenendo i tuoi diritti tramite un abbonamento di gruppo?
mrdenny,

Il mio account ha il proprio login, che ha i diritti di amministratore di sistema. Ha anche i diritti di amministratore del dominio tramite l'appartenenza al gruppo, quindi ciò dovrebbe darmi tutto ciò di cui ho bisogno e lo fa quando accedo usando le mie credenziali di Windows. Tuttavia, ho scoperto due cose. In primo luogo, se uso il codice sopra riportato nell'istruzione WITH di un proc memorizzato, mi dà un errore di sintassi. Se lo metto in una dichiarazione, funzionerà all'interno di un'istanza ma non tra istanze.
IAmTimCorey,

3

Dai un'occhiata all'utilizzo di EXECUTE AS+ Trustworthy. È possibile impostarlo dove può essere chiamato all'interno della procedura memorizzata purché l'utente b abbia avuto accesso e i due database si fidino l'uno dell'altro.

Questo blog di ragazzi dovrebbe rispondere o fornire tutto ciò di cui hai bisogno. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

l'uso della proprietà del database TRUSTWORTHY per controllare l'accesso alle risorse al di fuori dell'ambito del database di origine

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


Il problema che vedo è che Trustworthy stabilisce una relazione di fiducia tra i due database. Questo può essere sfruttato dai amministratori di sistema su entrambi i lati. Non lo voglio. Sto cercando di limitare le autorizzazioni di una persona. Se finisco per concedere a un'altra persona ancora più autorizzazioni, non sarà una buona cosa. Grazie comunque.
IAmTimCorey,

Nota qui che i singoli proprietari non devono essere persone fisiche, ma potrebbe essere un accesso generico per ciascun database. Non è necessario concedere l'intero database. Se non ti fidi dei amministratori di sistema sull'altro database, insisti sulla firma del certificato.
SoftwareCarpenter,

Hai detto di aver trovato il link sommarskog.se/grantperm.html nella tua risposta di seguito. Questo è lo stesso blog che ho pubblicato nella risposta che ho suggerito. "Questo blog di ragazzi dovrebbe rispondere o fornire tutto ciò di cui hai bisogno. Sommarskog.se/grantperm.html#EXECAScrossdb " Forse ti stavi solo riferendo per altri. Sono d'accordo che è un buon blog e leggi. In bocca al lupo!
SoftwareCarpenter,

Sì, scusami ho dimenticato di dire che il link è venuto da te. Era una buona risorsa. Grazie per l'aiuto.
IAmTimCorey,

2

Dopo aver letto ampiamente sull'argomento e aver fatto una serie di esperimenti, credo di essere giunto a una conclusione su questo argomento. L'istruzione EXECUTE AS non è progettata per funzionare su più istanze senza importanti implicazioni per la sicurezza. Quello che speravo era un modo per dire alla mia procedura con quale identità di Windows avrei voluto eseguire, poiché un'identità di Windows può avere accesso a più risorse su più server. Tuttavia, anche dopo aver giocato con un sacco di impostazioni diverse, è diventato evidente che avrei dovuto indebolire altre misure di sicurezza per consentire a una procedura memorizzata di impersonarmi.

Sembra che non ci siano molte informazioni là fuori sulle procedure tra istanze o tra server. Immagino che il motivo sia dovuto alle implicazioni in termini di sicurezza e prestazioni. Tuttavia, credo che ci siano casi in cui è importante e sembra che le soluzioni per farlo siano complicate e molto specifiche per lo scenario. Mi sono imbattuto in un buon articolo che mi ha aiutato almeno a capire alcune delle mie opzioni. Non era focalizzato sull'accesso tra istanze ma mi ha dato gli indizi che stavo cercando. Ti incoraggio a dare un'occhiata:

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

Sarei comunque interessato ad altre soluzioni a questo problema, ma la mia soluzione in questo momento è duplice. Innanzitutto, se devo assolutamente accedere a due database tramite una procedura memorizzata, devo utilizzare un account di accesso di Windows. Lo evito ogni volta che è possibile, tuttavia, poiché causa problemi di prestazioni (blocco multi-server, complicazioni di rete, incapacità di ottimizzare la query, ecc.) In secondo luogo, porto i dati da ciascun database attraverso chiamate separate, specifiche del database. Ciò significa che restituisco i dati al client prima di unirli. Non è performante o pulito come vorrei, ma sembra essere la soluzione più sicura.


1

Se è necessario accedere agli oggetti del database tra due istanze del server SQL, consiglierei una delle seguenti:

  1. Creare e utilizzare un server collegato tra le due istanze con l'autorizzazione appropriata per accedere all'oggetto sull'istanza di destinazione (remota).
  2. Utilizzare SSIS e richiamare il pacchetto dall'istanza di origine di SQL Server. A seconda della versione di SQL Server utilizzata, è possibile disporre di un processo SQL Agent (non pianificato per l'esecuzione, ma chiamato dalla procedura memorizzata) o utilizzare SSISDB per richiamare il pacchetto SSIS che accederà all'oggetto database sull'istanza remota.
  3. Spostare la logica sul livello intermedio (o sul lato dell'applicazione client)
  4. Creare un CLR per accedere all'oggetto del database remoto Di questi probabilmente utilizzerei il CLR per accedere al server dell'istanza remoto ed eseguire la procedura memorizzata. Sarà necessario concedere all'account eseguito l'istanza del server SQL di origine con accesso all'istanza del server SQL remoto.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.