Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule opisano sposób przenoszenia identyfikatorów logowania i haseł między różnymi wystąpieniami programu Microsoft SQL Server uruchomionym w systemie Windows. Wystąpienia mogą znajdować się na tym samym serwerze lub na różnych serwerach, a ich wersje mogą się różnić.
Oryginalna wersja produktu: SQL Server
Oryginalny numer KB: 918992, 246133
Dlaczego warto przenieść identyfikatory logowania między wystąpieniami programu SQL Server?
W tym artykule serwer A i serwer B są serwerami.
Po przeniesieniu bazy danych z wystąpienia programu SQL Server na serwerze A do wystąpienia programu SQL Server na serwerze B użytkownicy mogą nie zalogować się do serwera bazy danych na serwerze B. Ponadto użytkownicy mogą otrzymać następujący komunikat o błędzie:
Logowanie użytkownika 'MyUser' nie powiodło się. (System Microsoft SQL Server Compact, błąd: 18456)
Ten problem występuje, ponieważ identyfikatory logowania z wystąpienia programu SQL Server na serwerze A nie istnieją w wystąpieniu programu SQL Server na serwerze B.
Pamiętaj, że błąd 18456 występuje z wielu innych powodów. Aby uzyskać więcej informacji na temat tych przyczyn i ich rozwiązań, zobacz MSSQLSERVER_18456.
Procedura przenoszenia identyfikatorów logowania między wystąpieniami programu SQL Server
W celu przeniesienia loginów zastosuj jedną z następujących metod zależnie od systemu operacyjnego:
Metoda 1. Generowanie skryptów za pośrednictwem programu SSMS na serwerze źródłowym i ręczne resetowanie haseł dla identyfikatorów logowania programu SQL Server na serwerze docelowym
Skrypty logowania można wygenerować w programie SQL Server Management Studio (SSMS) przy użyciu opcji Generuj skrypty dla bazy danych.
Aby wygenerować skrypty za pośrednictwem programu SSMS na serwerze źródłowym i ręcznie zresetować hasła logowania programu SQL Server na serwerze docelowym, wykonaj następujące kroki:
Połącz się z serwerem A hostujący źródłowy program SQL Server.
Rozwiń węzeł Bazy danych.
Kliknij prawym przyciskiem myszy dowolną bazę danych użytkownika i wybierz pozycję Zadania>Generuj skrypty.
Zostanie otwarta strona Wprowadzenie . Wybierz przycisk Dalej , aby otworzyć stronę Wybierz obiekty . Wybierz pozycję Skrypt całej bazy danych i wszystkich obiektów bazy danych.
Wybierz przycisk Dalej , aby otworzyć stronę Ustaw opcje skryptów.
Wybierz przycisk Zaawansowane w obszarze Opcje logowania skryptu.
Na liście Zaawansowane znajdź pozycję Identyfikatory logowania skryptu, ustaw opcję True i wybierz przycisk OK.
Wróć do pozycji Ustaw opcje skryptów w obszarze Wybierz sposób zapisywania skryptów i wybierz pozycję Otwórz w nowym oknie zapytania.
Wybierz przycisk Dalej dwa razy, a następnie wybierz pozycję Zakończ.
Znajdź sekcję w skrycie zawierającym identyfikatory logowania. Zazwyczaj wygenerowany skrypt zawiera tekst z następującym komentarzem na początku tej sekcji:
/* For security reasons the login is created disabled and with a random password. */Uwaga 16.
Oznacza to, że identyfikatory logowania uwierzytelniania programu SQL Server są generowane przy użyciu losowego hasła i są domyślnie wyłączone. Musisz zresetować hasło i ponownie włączyć te identyfikatory logowania na serwerze docelowym.
Zastosuj skrypt logowania z większego wygenerowanego skryptu do docelowego programu SQL Server.
W przypadku wszystkich logowań uwierzytelniania programu SQL Server zresetuj hasło w docelowym programie SQL Server i ponownie włącz te identyfikatory logowania.
Metoda 2. Przenoszenie identyfikatorów logowania i haseł na serwer docelowy (serwer B) przy użyciu skryptów wygenerowanych na serwerze źródłowym (serwer A)
Utwórz procedury składowane, które pomogą wygenerować skrypty niezbędne do transferu identyfikatorów logowania i ich haseł. W tym celu połącz się z serwerem A przy użyciu SQL Server Management Studio (SSMS) lub dowolnego innego narzędzia klienckiego i uruchom następujący skrypt:
USE [master] GO IF OBJECT_ID('dbo.sp_hexadecimal') IS NOT NULL DROP PROCEDURE dbo.sp_hexadecimal GO CREATE PROCEDURE dbo.sp_hexadecimal @binvalue [varbinary](256) ,@hexvalue [nvarchar] (514) OUTPUT AS BEGIN DECLARE @i [smallint] DECLARE @length [smallint] DECLARE @hexstring [nchar](16) SELECT @hexvalue = N'0x' SELECT @i = 1 SELECT @length = DATALENGTH(@binvalue) SELECT @hexstring = N'0123456789ABCDEF' WHILE (@i < = @length) BEGIN DECLARE @tempint [smallint] DECLARE @firstint [smallint] DECLARE @secondint [smallint] SELECT @tempint = CONVERT([smallint], SUBSTRING(@binvalue, @i, 1)) SELECT @firstint = FLOOR(@tempint / 16) SELECT @secondint = @tempint - (@firstint * 16) SELECT @hexvalue = @hexvalue + SUBSTRING(@hexstring, @firstint + 1, 1) + SUBSTRING(@hexstring, @secondint + 1, 1) SELECT @i = @i + 1 END END GO IF OBJECT_ID('dbo.sp_help_revlogin') IS NOT NULL DROP PROCEDURE dbo.sp_help_revlogin GO CREATE PROCEDURE dbo.sp_help_revlogin @login_name [sysname] = NULL AS BEGIN DECLARE @name [sysname] DECLARE @type [nvarchar](1) DECLARE @hasaccess [int] DECLARE @denylogin [int] DECLARE @is_disabled [int] DECLARE @PWD_varbinary [varbinary](256) DECLARE @PWD_string [nvarchar](514) DECLARE @SID_varbinary [varbinary](85) DECLARE @SID_string [nvarchar](514) DECLARE @tmpstr [nvarchar](4000) DECLARE @is_policy_checked [nvarchar](3) DECLARE @is_expiration_checked [nvarchar](3) DECLARE @Prefix [nvarchar](4000) DECLARE @defaultdb [sysname] DECLARE @defaultlanguage [sysname] DECLARE @tmpstrRole [nvarchar](4000) IF @login_name IS NULL BEGIN DECLARE login_curs CURSOR FOR SELECT p.[sid],p.[name],p.[type],p.is_disabled,p.default_database_name,l.hasaccess,l.denylogin,default_language_name = ISNULL(p.default_language_name,@@LANGUAGE) FROM sys.server_principals p LEFT JOIN sys.syslogins l ON l.[name] = p.[name] WHERE p.[type] IN ('S' /* SQL_LOGIN */,'G' /* WINDOWS_GROUP */,'U' /* WINDOWS_LOGIN */) AND p.[name] <> 'sa' AND p.[name] not like '##%' ORDER BY p.[name] END ELSE DECLARE login_curs CURSOR FOR SELECT p.[sid],p.[name],p.[type],p.is_disabled,p.default_database_name,l.hasaccess,l.denylogin,default_language_name = ISNULL(p.default_language_name,@@LANGUAGE) FROM sys.server_principals p LEFT JOIN sys.syslogins l ON l.[name] = p.[name] WHERE p.[type] IN ('S' /* SQL_LOGIN */,'G' /* WINDOWS_GROUP */,'U' /* WINDOWS_LOGIN */) AND p.[name] <> 'sa' AND p.[name] NOT LIKE '##%' AND p.[name] = @login_name ORDER BY p.[name] OPEN login_curs FETCH NEXT FROM login_curs INTO @SID_varbinary,@name,@type,@is_disabled,@defaultdb,@hasaccess,@denylogin,@defaultlanguage IF (@@fetch_status = - 1) BEGIN PRINT '/* No login(s) found for ' + QUOTENAME(@login_name) + N'. */' CLOSE login_curs DEALLOCATE login_curs RETURN - 1 END SET @tmpstr = N'/* sp_help_revlogin script ** Generated ' + CONVERT([nvarchar], GETDATE()) + N' on ' + @@SERVERNAME + N' */' PRINT @tmpstr WHILE (@@fetch_status <> - 1) BEGIN IF (@@fetch_status <> - 2) BEGIN PRINT '' SET @tmpstr = N'/* Login ' + QUOTENAME(@name) + N' */' PRINT @tmpstr SET @tmpstr = N'IF NOT EXISTS ( SELECT 1 FROM sys.server_principals WHERE [name] = N''' + @name + N''' ) BEGIN' PRINT @tmpstr IF @type IN ('G','U') -- NT-authenticated Group/User BEGIN -- NT authenticated account/group SET @tmpstr = N' CREATE LOGIN ' + QUOTENAME(@name) + N' FROM WINDOWS WITH DEFAULT_DATABASE = ' + QUOTENAME(@defaultdb) + N' ,DEFAULT_LANGUAGE = ' + QUOTENAME(@defaultlanguage) END ELSE BEGIN -- SQL Server authentication -- obtain password and sid SET @PWD_varbinary = CAST(LOGINPROPERTY(@name, 'PasswordHash') AS [varbinary](256)) EXEC dbo.sp_hexadecimal @PWD_varbinary, @PWD_string OUT EXEC dbo.sp_hexadecimal @SID_varbinary, @SID_string OUT -- obtain password policy state SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE [name] = @name SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE [name] = @name SET @tmpstr = NCHAR(9) + N'CREATE LOGIN ' + QUOTENAME(@name) + N' WITH PASSWORD = ' + @PWD_string + N' HASHED ,SID = ' + @SID_string + N' ,DEFAULT_DATABASE = ' + QUOTENAME(@defaultdb) + N' ,DEFAULT_LANGUAGE = ' + QUOTENAME(@defaultlanguage) IF @is_policy_checked IS NOT NULL BEGIN SET @tmpstr = @tmpstr + N' ,CHECK_POLICY = ' + @is_policy_checked END IF @is_expiration_checked IS NOT NULL BEGIN SET @tmpstr = @tmpstr + N' ,CHECK_EXPIRATION = ' + @is_expiration_checked END END IF (@denylogin = 1) BEGIN -- login is denied access SET @tmpstr = @tmpstr + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'' + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'DENY CONNECT SQL TO ' + QUOTENAME(@name) END ELSE IF (@hasaccess = 0) BEGIN -- login exists but does not have access SET @tmpstr = @tmpstr + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'' + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'REVOKE CONNECT SQL TO ' + QUOTENAME(@name) END IF (@is_disabled = 1) BEGIN -- login is disabled SET @tmpstr = @tmpstr + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'' + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'ALTER LOGIN ' + QUOTENAME(@name) + N' DISABLE' END SET @Prefix = NCHAR(13) + NCHAR(10) + NCHAR(9) + N'' + NCHAR(13) + NCHAR(10) + NCHAR(9) + N'EXEC [master].dbo.sp_addsrvrolemember @loginame = N''' SET @tmpstrRole = N'' SELECT @tmpstrRole = @tmpstrRole + CASE WHEN sysadmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''sysadmin''' ELSE '' END + CASE WHEN securityadmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''securityadmin''' ELSE '' END + CASE WHEN serveradmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''serveradmin''' ELSE '' END + CASE WHEN setupadmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''setupadmin''' ELSE '' END + CASE WHEN processadmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''processadmin''' ELSE '' END + CASE WHEN diskadmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''diskadmin''' ELSE '' END + CASE WHEN dbcreator = 1 THEN @Prefix + LoginName + N''', @rolename = N''dbcreator''' ELSE '' END + CASE WHEN bulkadmin = 1 THEN @Prefix + LoginName + N''', @rolename = N''bulkadmin''' ELSE '' END FROM ( SELECT SUSER_SNAME([sid])AS LoginName ,sysadmin ,securityadmin ,serveradmin ,setupadmin ,processadmin ,diskadmin ,dbcreator ,bulkadmin FROM sys.syslogins WHERE ( sysadmin <> 0 OR securityadmin <> 0 OR serveradmin <> 0 OR setupadmin <> 0 OR processadmin <> 0 OR diskadmin <> 0 OR dbcreator <> 0 OR bulkadmin <> 0 ) AND [name] = @name ) L IF @tmpstr <> '' PRINT @tmpstr IF @tmpstrRole <> '' PRINT @tmpstrRole PRINT 'END' END FETCH NEXT FROM login_curs INTO @SID_varbinary,@name,@type,@is_disabled,@defaultdb,@hasaccess,@denylogin,@defaultlanguage END CLOSE login_curs DEALLOCATE login_curs RETURN 0 ENDUwaga 16.
Ten skrypt tworzy dwie procedury składowane w głównej bazie danych. Procedury są nazywane sp_hexadecimal i sp_help_revlogin.
W edytorze zapytań SSMS wybierz opcję Wyniki do tekstu.
Uruchom następującą instrukcję w tym samym lub nowym oknie zapytania:
EXEC sp_help_revloginSkrypt wyjściowy generowany przez procedurę składowaną
sp_help_revloginto skrypt logowania. Ten skrypt logowania tworzy identyfikatory logowania z oryginalnym identyfikatorem zabezpieczeń (SID) i oryginalnym hasłem.Przejrzyj i postępuj zgodnie z informacjami w sekcji Dodatkowe zagadnienia dotyczące przenoszenia identyfikatorów logowania programu SQL Server przed przystąpieniem do implementowania kroków na serwerze docelowym.
Po zaimplementowaniu wszelkich odpowiednich kroków z sekcji Dodatkowe zagadnienia dotyczące przenoszenia identyfikatorów logowania programu SQL Server nawiąż połączenie z serwerem docelowym B przy użyciu dowolnego narzędzia klienckiego (takiego jak program SSMS).
Uruchom skrypt wygenerowany jako dane wyjściowe
sp_helprevloginz serwera A.
Dodatkowe zagadnienia dotyczące przenoszenia identyfikatorów logowania programu SQL Server
Przed uruchomieniem skryptu wyjściowego na wystąpieniu na serwerze B przejrzyj następujące informacje:
Zrozumienie haszowania haseł w transferach logowania w SQL Server
Hasło może być skrótem w następujący sposób:
-
VERSION_SHA1: Ten skrót jest generowany przy użyciu algorytmu SHA1 i jest używany w SQL Server od 2000 do SQL Server 2008 R2. -
VERSION_SHA2: Ten skrót jest generowany przy użyciu algorytmu SHA2 512 i jest używany w wersjach SQL Server 2012 i nowszych.
-
W skrypcie danych wyjściowych nazwy logowania są tworzone przy użyciu zaszyfrowanego hasła. Wynika to z argumentu
HASHEDw instrukcjiCREATE LOGIN. Ten argument określa, że hasło wprowadzone po argumenciePASSWORDjest już skrótem.
Obsługa zmian domeny podczas transferów logowania programu SQL Server
Czy serwery źródłowe i docelowe znajdują się w różnych domenach? Dokładnie przejrzyj skrypt wyjściowy. Jeśli serwer A i serwer B znajdują się w różnych domenach, musisz zmienić skrypt wyjściowy. Następnie należy zastąpić oryginalną nazwę domeny przy użyciu nowej nazwy domeny w instrukcjach CREATE LOGIN . Zintegrowane identyfikatory logowania, którym udzielono dostępu w nowej domenie, nie mają tego samego identyfikatora SID co identyfikatory logowania w oryginalnej domenie. W związku z tym użytkownicy są oddzieleni od tych identyfikatorów logowania. Aby uzyskać więcej informacji na temat rozwiązywania problemów z tymi oddzielonych użytkownikami, zobacz Rozwiązywanie problemów z oddzielonych użytkownikami (SQL Server) i ALTER USER.
Jeśli serwer A i serwer B znajdują się w tej samej domenie, jest używany ten sam identyfikator SID. Dlatego jest mało prawdopodobne, że użytkownicy zostaną oddzieleni.
Wymagane uprawnienia do wyświetlania i wybierania identyfikatorów logowania programu SQL Server
Domyślnie tylko członek stałej roli serwera sysadmin może uruchamiać instrukcję SELECT z widoku sys.server_principals. Jeśli członek stałej roli serwera sysadmin nie przyznaje użytkownikom niezbędnych uprawnień, użytkownicy nie mogą tworzyć ani uruchamiać skryptu wyjściowego.
Domyślne ustawienie bazy danych nie jest skryptowe i przesyłane
Kroki opisane w tym artykule nie przesyłają domyślnych informacji o bazie danych dla określonego identyfikatora logowania. Dzieje się tak, ponieważ domyślna baza danych może nie zawsze istnieć na serwerze B. Aby zdefiniować domyślną bazę danych logowania, użyj ALTER LOGIN instrukcji , przekazując nazwę logowania i domyślną bazę danych jako argumenty.
Zarządzanie różnicami kolejności sortowania w transferach logowania programu SQL Server
Mogą istnieć różnice w kolejności sortowania między serwerami źródłowymi i docelowymi lub mogą być takie same. Oto jak można rozwiązać każdy scenariusz:
Bez uwzględniania wielkości liter serwer A i serwer z uwzględnieniem wielkości liter B: kolejność sortowania serwera A może być bez uwzględniania wielkości liter, a kolejność sortowania serwera B może mieć wielkość liter. W takim przypadku użytkownicy muszą wpisać hasła we wszystkich wielkich literach po przeniesieniu identyfikatorów logowania i haseł do wystąpienia na serwerze B.
Serwer uwzględniający wielkość liter A i serwer bez uwzględniania wielkości liter B: kolejność sortowania serwera A może mieć wielkość liter, a kolejność sortowania serwera B może być bez uwzględniania wielkości liter. W takim przypadku użytkownicy nie mogą logować się przy użyciu identyfikatorów logowania i haseł przesyłanych do wystąpienia na serwerze B, chyba że spełniony jest jeden z następujących warunków:
- Oryginalne hasła nie zawierają żadnych liter.
- Wszystkie litery w oryginalnych hasłach są wielkimi literami.
Uwzględniana wielkość liter lub wielkość liter na obu serwerach: kolejność sortowania zarówno serwera A, jak i serwera B może mieć wielkość liter, lub kolejność sortowania zarówno serwera A, jak i serwera B, może mieć wielkość liter. W takich przypadkach użytkownicy nie mają problemu.
Rozwiąż konflikty z istniejącymi loginami SQL Server na serwerze docelowym
Skrypt został zaprojektowany tak, aby sprawdzić, czy logowanie istnieje na serwerze docelowym i utworzyć identyfikator logowania tylko wtedy, gdy nie. Jeśli jednak podczas uruchamiania skryptu wyjściowego na wystąpieniu na serwerze B zostanie wyświetlony następujący komunikat o błędzie, należy go ręcznie rozwiązać, wykonując kroki opisane w tej sekcji.
Komunikat 15025, Poziom 16, Stan 1, Wiersz 1
Jednostka serwera 'MyLogin' już istnieje.
Podobnie identyfikator logowania, który znajduje się już w wystąpieniu na serwerze B, może mieć identyfikator SID, który jest taki sam jak identyfikator SID w skry skryptzie wyjściowym. W takim przypadku podczas uruchamiania skryptu wyjściowego na wystąpieniu na serwerze B zostanie wyświetlony następujący komunikat o błędzie:
Komunikat 15433, Poziom 16, Stan 1, Wiersz 1 Podany identyfikator sid parametru jest w użyciu.
Aby ręcznie rozwiązać ten problem, wykonaj następujące kroki:
- Dokładnie przejrzyj skrypt wyjściowy.
- Sprawdź zawartość
sys.server_principalswidoku w wystąpieniu na serwerze B. - W razie potrzeby rozwiąż te komunikaty o błędach.
Począwszy od programu SQL Server 2005, identyfikator SID logowania służy do zarządzania dostępem na poziomie bazy danych. Czasami identyfikator logowania może mieć różne identyfikatory SID, gdy są mapowane na użytkowników w różnych bazach danych. Ten problem może wystąpić, jeśli bazy danych są ręcznie łączone z różnych serwerów. W takich przypadkach identyfikator logowania może uzyskać dostęp tylko do bazy danych, w której identyfikator SID podmiotu zabezpieczeń bazy danych jest zgodny z identyfikatorem sys.server_principals SID w widoku. Aby rozwiązać ten problem, ręcznie usuń użytkownika bazy danych z niezgodnym identyfikatorem SID przy użyciu instrukcji DROP USER . Następnie ponownie dodaj użytkownika za pomocą instrukcji CREATE USER i zamapuj go na poprawną nazwę logowania (podmiot zabezpieczeń serwera).
Aby uzyskać więcej informacji i odróżnić serwery od podmiotów zabezpieczeń bazy danych, zobacz CREATE USER (TWORZENIE UŻYTKOWNIKA ) i CREATE LOGIN (TWORZENIE IDENTYFIKATORA LOGOWANIA).