Podczas konfigurowania połączonego serwera w SQL Server, konfigurowanie loginów może czasami być mylące. W tym artykule zamierzam przedstawić ogólny przegląd tego, w jaki sposób SQL Server mapuje lokalne logowanie na zdalne logowanie na połączonym serwerze.
Gdy używasz sp_addlinkedserver
aby utworzyć połączony serwer w SQL Server, automatycznie tworzone jest domyślne mapowanie między wszystkimi loginami na serwerze lokalnym a zdalnymi loginami na serwerze linked. SQL Server używa poświadczeń logowania lokalnego podczas łączenia się z serwerem połączonym w imieniu logowania.
Jeśli więc twój lokalny login ma odpowiedni login na połączonym serwerze, z tymi samymi poświadczeniami i ma odpowiednie uprawnienia, będziesz mógł połączyć się przy użyciu lokalnego loginu. Nie ma potrzeby dodawania loginu do połączonego serwera (zakładając, że jesteś zadowolony z połączenia przy użyciu własnego lokalnego loginu).
Ale jeśli lokalny login nie mieć odpowiedni login na połączonym serwerze (z tymi samymi danymi uwierzytelniającymi), połączenie nie powiedzie się.
W takich przypadkach możesz użyć sp_addlinkedsrvlogin
aby stworzyć login dla linked server’a, aby lokalne loginy mogły łączyć się z linked server’em, nawet jeśli nie mają odpowiedniego loginu na linked serverze.
Może to skutkować używaniem różnych użytkowników na serwerze zlinkowanym, w zależności od tego, czy mają oni odpowiedni login na serwerze zlinkowanym.
W przypadku użytkowników połączonych z SQL Server za pomocą trybu uwierzytelniania Windows, SQL Server może automatycznie używać poświadczeń bezpieczeństwa Windows, o ile delegowanie kont bezpieczeństwa jest dostępne na kliencie i serwerze wysyłającym, a dostawca obsługuje tryb uwierzytelniania Windows.
Przykłady na tej stronie używają logowania SQL Server (nie używają trybu uwierzytelniania Windows). Te przykłady pokazują wyniki, które otrzymuję, logując się do połączonego serwera w różnych scenariuszach przy użyciu lokalnych loginów SQL Server.
Przykład 1 – połączony serwer bez jawnego logowania
Najpierw stworzę połączony serwer o nazwie Homer, ale nie stworzę żadnych powiązanych loginów.
EXEC sp_addlinkedserver @server=N'Homer', @srvproduct=N'', @provider=N'MSOLEDBSQL', @datasrc=N'172.17.0.2', @catalog='Music';
Spowoduje to automatyczne utworzenie domyślnego mapowania między wszystkimi logowaniami na serwerze lokalnym a zdalnymi logowaniami na serwerze połączonym.
Teraz spróbuję uruchomić następujące zapytanie przekazujące dla połączonego serwera przy użyciu różnych lokalnych loginów:
SELECT * FROM OPENQUERY( Homer, 'SELECT CURRENT_USER AS ''CURRENT_USER'', ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN''' );
Wyniki zapytania są następujące.
sa
Login failed for user 'sa'.
Szczegóły logowania :Na obu serwerach jest login o nazwie „sa”, ale mają różne hasła. Obaj są członkami sysadmin rola serwera.
Liza
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | dbo | Lisa | +----------------+------------------+
Szczegóły logowania :Na obu serwerach jest login o nazwie „Lisa” i mają to samo hasło. Obaj są członkami sysadmin rola serwera.
Molarnia
Login failed for user 'Milhouse'.
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Apu
Login failed for user 'Apu'.
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Przykład 2 – Dodaj login do połączonego serwera
Następnie stworzę login do połączonego serwera.
EXEC sp_addlinkedsrvlogin @rmtsrvname=N'Homer', @useself=N'FALSE', @locallogin=NULL, @rmtuser=N'Maggie', @rmtpassword=N'BigStrong#Passw0rd';
Ten login odpowiada loginowi na zdalnym serwerze, więc między nimi tworzone jest mapowanie.
Teraz każdy użytkownik ponownie uruchomi następujące zapytanie:
SELECT * FROM OPENQUERY( Homer, 'SELECT CURRENT_USER AS ''CURRENT_USER'', ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN''' );
Wyniki zapytania są następujące.
sa
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | Maggie | Maggie | +----------------+------------------+
Szczegóły logowania :Na obu serwerach jest login o nazwie „sa”, ale mają różne hasła. Obaj są członkami sysadmin rola serwera.
Liza
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | Maggie | Maggie | +----------------+------------------+
Szczegóły logowania :Na obu serwerach jest login o nazwie „Lisa” i mają to samo hasło. Obaj są członkami sysadmin rola serwera.
Molarnia
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | Maggie | Maggie | +----------------+------------------+
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Apu
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | Maggie | Maggie | +----------------+------------------+
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Więc wszystkie lokalne loginy były w stanie połączyć się z połączonym serwerem. Nawet loginy, które nie mają odpowiedniego zdalnego logowania na połączonym serwerze, były w stanie się połączyć. To dlatego, że wszyscy używali loginu Maggie. Dzięki Maggie!
Przykład 3 – Ogranicz logowanie
Teraz zaktualizuję login do połączonego serwera, aby był ograniczony do Milhouse.
Ale żeby to zrobić, muszę usunąć połączony serwer i utworzyć go ponownie. Jeśli tego nie zrobię, SQL Server użyje istniejących mapowań i uzyskam takie same wyniki jak powyżej.
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';
Więc w tym przypadku używam @locallogin='Milhouse'
(zamiast @locallogin=NULL
jak w poprzednim przykładzie). Spowoduje to dodanie mapowania logowania tylko dla jednego lokalnego logowania (Milhouse).
Każdy użytkownik ponownie uruchamia następujące zapytanie:
SELECT * FROM OPENQUERY( Homer, 'SELECT CURRENT_USER AS ''CURRENT_USER'', ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN''' );
Wyniki zapytania są następujące.
sa
Msg 18456, Level 14, State 1, Line 1 Login failed for user 'sa'.
Szczegóły logowania :Na obu serwerach jest login o nazwie „sa”, ale mają różne hasła. Obaj są członkami sysadmin rola serwera.
Liza
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | dbo | Lisa | +----------------+------------------+
Szczegóły logowania :Na obu serwerach jest login o nazwie „Lisa” i mają to samo hasło. Obaj są członkami sysadmin rola serwera.
Molarnia
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | Maggie | Maggie | +----------------+------------------+
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Apu
Msg 18456, Level 14, State 1, Line 1 Login failed for user 'Apu'.
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Kluczową kwestią jest to, że nawet jeśli ograniczysz logowanie tylko do jednego lokalnego loginu, nie przeszkadza to innym lokalnym logowaniu w łączeniu się z połączonym serwerem. Jeśli mają odpowiedni login na połączonym serwerze, będą mogli uzyskać do niego dostęp za pomocą własnego mapowania logowania, które zostało utworzone, gdy sp_addlinkedserver
został uruchomiony.
Przykład 4 – Właściwie ogranicz tylko do jednego logowania
Jeśli naprawdę chcesz ograniczyć to tylko do jednego loginu i nic więcej, możesz użyć sp_droplinkedsrvlogin
aby usunąć wszystkie mapowania logowania, które sp_addlinkedserver
tworzy przed wykonaniem 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';
Teraz uruchommy zapytanie jeszcze raz przy każdym logowaniu:
SELECT * FROM OPENQUERY( Homer, 'SELECT CURRENT_USER AS ''CURRENT_USER'', ORIGINAL_LOGIN() AS ''ORIGINAL_LOGIN''' );
Wyniki zapytania są następujące.
sa
Msg 7416, Level 16, State 1, Line 1 Access to the remote server is denied because no login-mapping exists.
Szczegóły logowania :Na obu serwerach jest login o nazwie „sa”, ale mają różne hasła. Obaj są członkami sysadmin rola serwera.
Liza
Msg 7416, Level 16, State 1, Line 1 Access to the remote server is denied because no login-mapping exists.
Szczegóły logowania :Na obu serwerach jest login o nazwie „Lisa” i mają to samo hasło. Obaj są członkami sysadmin rola serwera.
Molarnia
+----------------+------------------+ | CURRENT_USER | ORIGINAL_LOGIN | |----------------+------------------| | Maggie | Maggie | +----------------+------------------+
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Apu
Msg 7416, Level 16, State 1, Line 1 Access to the remote server is denied because no login-mapping exists.
Szczegóły logowania :Ten login jest tylko na serwerze lokalnym. Nie ma odpowiedniego loginu na połączonym serwerze.
Konfiguracja zdalnego logowania
Pomyślne połączenie z połączonym serwerem to tylko pierwszy krok w tym procesie. Po połączeniu na możliwość wykonywania różnych czynności będą miały wpływ uprawnienia zdalnego użytkownika, do którego zmapowany jest Twój login.
Na przykład, jeśli Maggie została utworzona na zdalnym serwerze w następujący sposób:
CREATE LOGIN Maggie WITH PASSWORD = 'BigStrong#Passw0rd'; USE Music; CREATE USER Maggie FOR LOGIN Maggie; GRANT SELECT ON DATABASE::Music TO Maggie;
Wszystko, co może zrobić, to uruchomić SELECT
oświadczenia przeciwko bazie „Muzyka”. Dlatego każdy, kto łączy się z połączonym serwerem za pomocą loginu Maggie, będzie ograniczony tylko do tego.
Dobrą praktyką jest udzielanie tylko wymaganych uprawnień, ale nie więcej.
Oficjalna dokumentacja
Ten artykuł miał na celu przedstawienie ogólnego przeglądu sposobu, w jaki logowanie działa na serwerach połączonych. Jest wiele innych scenariuszy, których tutaj nie omówiłem.
Jeśli chcesz dowiedzieć się więcej, zapoznaj się z następującymi linkami do dokumentacji firmy Microsoft:
sp_addlinkedserver
sp_addlinkedsrvlogin
sp_testlinkedserver
-
sp_droplinkedsrvlogin
-
sp_dropserver
OPENQUERY()