Database
 sql >> Database >  >> RDS >> Database

Come funzionano gli accessi sui server collegati (esempi T-SQL)

Quando si configura un server collegato in SQL Server, la configurazione degli accessi a volte può creare confusione. In questo articolo, intendo fornire una panoramica di alto livello su come SQL Server esegue il mapping degli accessi locali agli accessi remoti sul server collegato.

Quando usi sp_addlinkedserver per creare un server collegato in SQL Server, viene creata automaticamente una mappatura predefinita tra tutti gli accessi sul server locale e gli accessi remoti sul server collegato. SQL Server utilizza le credenziali dell'accesso locale durante la connessione al server collegato per conto dell'accesso.

Quindi, se il tuo accesso locale ha un accesso corrispondente sul server collegato, con le stesse credenziali e dispone delle autorizzazioni appropriate, sarai in grado di connetterti utilizzando il tuo accesso locale. Non è necessario aggiungere un login per il server collegato (supponendo che tu sia felice di connetterti utilizzando il tuo login locale).

Ma se il tuo login locale non lo fa avere un login corrispondente sul server collegato (e con le stesse credenziali), la connessione fallirà.

In questi casi, puoi utilizzare sp_addlinkedsrvlogin per creare un login per il server collegato in modo che gli accessi locali possano connettersi al server collegato anche quando non hanno un login corrispondente sul server collegato.

Ciò potrebbe comportare l'utilizzo di utenti diversi sul server collegato, a seconda che dispongano o meno di un accesso corrispondente sul server collegato.

Per gli utenti connessi a SQL Server tramite la modalità di autenticazione di Windows, SQL Server può utilizzare automaticamente le credenziali di sicurezza di Windows purché la delega dell'account di sicurezza sia disponibile sul client e sul server di invio e il provider supporti la modalità di autenticazione di Windows.

Gli esempi in questa pagina usano gli accessi di SQL Server (non usano la modalità di autenticazione di Windows). Questi esempi mostrano i risultati che ottengo quando accedo a un server collegato in diversi scenari utilizzando gli accessi locali di SQL Server.

Esempio 1 – Server collegato senza accesso esplicito

Per prima cosa creerò un server collegato chiamato Homer, ma non creerò accessi associati.

EXEC sp_addlinkedserver 
    @server=N'Homer', 
    @srvproduct=N'', 
    @provider=N'MSOLEDBSQL', 
    @datasrc=N'172.17.0.2',
    @catalog='Music';

Questo crea automaticamente una mappatura predefinita tra tutti gli accessi sul server locale e gli accessi remoti sul server collegato.

Ora proverò a eseguire la seguente query pass-through sul server collegato utilizzando vari accessi locali:

SELECT * FROM OPENQUERY(
    Homer,
    'SELECT 
       CURRENT_USER AS ''CURRENT_USER'', 
       ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN'''
);

I risultati della query sono i seguenti.

sa

Login failed for user 'sa'.

Dettagli di accesso :C'è un login chiamato "sa" su entrambi i server, ma hanno password diverse. Entrambi sono membri del amministratore di sistema ruolo del server.

Lisa

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| dbo            | Lisa             |
+----------------+------------------+

Dettagli di accesso :C'è un login chiamato "Lisa" su entrambi i server e hanno la stessa password. Entrambi sono membri del amministratore di sistema ruolo del server.

Milhouse

Login failed for user 'Milhouse'.

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Apu

Login failed for user 'Apu'.

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Esempio 2:aggiungere un accesso per il server collegato

Successivamente, creerò un accesso per il server collegato.

EXEC sp_addlinkedsrvlogin 
    @rmtsrvname=N'Homer', 
    @useself=N'FALSE', 
    @locallogin=NULL, 
    @rmtuser=N'Maggie', 
    @rmtpassword=N'BigStrong#Passw0rd';

Questo login corrisponde a un login sul server remoto, quindi viene creata una mappatura tra di loro.

Ora ogni utente eseguirà nuovamente la seguente query:

SELECT * FROM OPENQUERY(
    Homer,
    'SELECT 
       CURRENT_USER AS ''CURRENT_USER'', 
       ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN'''
);

I risultati della query sono i seguenti.

sa

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| Maggie         | Maggie           |
+----------------+------------------+

Dettagli di accesso :C'è un login chiamato "sa" su entrambi i server, ma hanno password diverse. Entrambi sono membri del amministratore di sistema ruolo del server.

Lisa

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| Maggie         | Maggie           |
+----------------+------------------+

Dettagli di accesso :C'è un login chiamato "Lisa" su entrambi i server e hanno la stessa password. Entrambi sono membri del amministratore di sistema ruolo del server.

Milhouse

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| Maggie         | Maggie           |
+----------------+------------------+

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Apu

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| Maggie         | Maggie           |
+----------------+------------------+

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Quindi tutti gli accessi locali sono stati in grado di connettersi al server collegato. Anche gli accessi che non hanno un accesso remoto corrispondente sul server collegato sono stati in grado di connettersi. Questo perché tutti hanno usato il login Maggie. Grazie Maggie!

Esempio 3 – Limitare l'accesso

Ora aggiornerò il login per il server collegato in modo che sia limitato a Milhouse.

Ma per fare ciò, dovrò rimuovere il server collegato e crearlo di nuovo. Se non lo faccio, SQL Server utilizzerà i mapping esistenti e otterrò gli stessi risultati di cui sopra.

EXEC sp_dropserver 'Homer', 'droplogins';

EXEC sp_addlinkedserver 
    @server=N'Homer', 
    @srvproduct=N'', 
    @provider=N'MSOLEDBSQL', 
    @datasrc=N'172.17.0.2',
    @catalog='Music';

EXEC sp_addlinkedsrvlogin 
    @rmtsrvname=N'Homer', 
    @useself=N'FALSE', 
    @locallogin='Milhouse', 
    @rmtuser=N'Maggie', 
    @rmtpassword=N'BigStrong#Passw0rd';

Quindi in questo caso uso @locallogin='Milhouse' (invece di @locallogin=NULL come nell'esempio precedente). Questo aggiungerà una mappatura di accesso per un solo accesso locale (Milhouse).

Ogni utente esegue nuovamente la seguente query:

SELECT * FROM OPENQUERY(
    Homer,
    'SELECT 
       CURRENT_USER AS ''CURRENT_USER'', 
       ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN'''
);

I risultati della query sono i seguenti.

sa

Msg 18456, Level 14, State 1, Line 1
Login failed for user 'sa'.

Dettagli di accesso :C'è un login chiamato "sa" su entrambi i server, ma hanno password diverse. Entrambi sono membri del amministratore di sistema ruolo del server.

Lisa

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| dbo            | Lisa             |
+----------------+------------------+

Dettagli di accesso :C'è un login chiamato "Lisa" su entrambi i server e hanno la stessa password. Entrambi sono membri del amministratore di sistema ruolo del server.

Milhouse

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| Maggie         | Maggie           |
+----------------+------------------+

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Apu

Msg 18456, Level 14, State 1, Line 1
Login failed for user 'Apu'.

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Quindi la chiave da asporto qui è che, anche quando limiti l'accesso a un solo accesso locale, non impedisce ad altri accessi locali di connettersi al server collegato. Se hanno un accesso corrispondente sul server collegato, potranno accedervi utilizzando la propria mappatura di accesso creata quando sp_addlinkedserver è stato eseguito.

Esempio 4:limitarlo effettivamente a un solo accesso

Se vuoi davvero limitarlo a un solo accesso e non di più, puoi usare sp_droplinkedsrvlogin per eliminare tutte le mappature di accesso che sp_addlinkedserver crea prima di eseguire sp_addlinkedsrvlogin .

EXEC sp_dropserver 'Homer', 'droplogins';

EXEC sp_addlinkedserver 
    @server=N'Homer', 
    @srvproduct=N'', 
    @provider=N'MSOLEDBSQL', 
    @datasrc=N'172.17.0.2',
    @catalog='Music';

EXEC sp_droplinkedsrvlogin 'Homer', NULL;

EXEC sp_addlinkedsrvlogin 
    @rmtsrvname=N'Homer', 
    @useself=N'FALSE', 
    @locallogin='Milhouse', 
    @rmtuser=N'Maggie', 
    @rmtpassword=N'BigStrong#Passw0rd';

Ora eseguiamo nuovamente la query ad ogni accesso:

SELECT * FROM OPENQUERY(
    Homer,
    'SELECT 
       CURRENT_USER AS ''CURRENT_USER'', 
       ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN'''
);

I risultati della query sono i seguenti.

sa

Msg 7416, Level 16, State 1, Line 1
Access to the remote server is denied because no login-mapping exists.

Dettagli di accesso :C'è un login chiamato "sa" su entrambi i server, ma hanno password diverse. Entrambi sono membri del amministratore di sistema ruolo del server.

Lisa

Msg 7416, Level 16, State 1, Line 1
Access to the remote server is denied because no login-mapping exists.

Dettagli di accesso :C'è un login chiamato "Lisa" su entrambi i server e hanno la stessa password. Entrambi sono membri del amministratore di sistema ruolo del server.

Milhouse

+----------------+------------------+
| CURRENT_USER   | ORIGINAL_LOGIN   |
|----------------+------------------|
| Maggie         | Maggie           |
+----------------+------------------+

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Apu

Msg 7416, Level 16, State 1, Line 1
Access to the remote server is denied because no login-mapping exists.

Dettagli di accesso :Questo login è solo sul server locale. Non esiste un login corrispondente sul server collegato.

Configurazione dell'accesso remoto

La corretta connessione al server collegato è solo il primo passaggio del processo. Una volta connesso, la tua capacità di fare cose sarà influenzata dalle autorizzazioni dell'utente remoto a cui è mappato il tuo login.

Ad esempio, se Maggie è stata creata sul server remoto in questo modo:

CREATE LOGIN Maggie
    WITH PASSWORD = 'BigStrong#Passw0rd';

USE Music;
CREATE USER Maggie FOR LOGIN Maggie;

GRANT SELECT ON DATABASE::Music TO Maggie;

Tutto ciò che può fare è eseguire SELECT dichiarazioni contro il database "Musica". Pertanto, chiunque si connetta al server collegato utilizzando il login di Maggie sarà limitato a questo.

È buona norma concedere solo le autorizzazioni necessarie, ma non di più.

Documentazione ufficiale

Questo articolo aveva lo scopo di fornire una panoramica di alto livello su come funzionano gli accessi con i server collegati. Ci sono molti altri scenari che non ho trattato qui.

Se sei interessato a saperne di più, controlla i seguenti collegamenti alla documentazione di Microsoft:

  • sp_addlinkedserver
  • sp_addlinkedsrvlogin
  • sp_testlinkedserver
  • sp_droplinkedsrvlogin
  • sp_dropserver
  • OPENQUERY()