Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Versión del producto original: SQL Server
Número de KB original: 918992, 246133
Resumen
En este artículo se muestra cómo transferir SQL Server inicios de sesión y contraseñas entre instancias de Microsoft SQL Server que se ejecutan en Windows. Use estos procedimientos en escenarios de migración, restauración o alta disponibilidad de SQL Server para mantener intacta la autenticación de los usuarios y evitar que queden usuarios huérfanos en la base de datos de la instancia de destino. Las instancias de origen y destino pueden estar en el mismo servidor o en servidores diferentes, y sus versiones pueden diferir.
¿Por qué transferir inicios de sesión entre instancias de SQL Server?
Al mover una base de datos a un nuevo servidor, por ejemplo durante una migración o restauración, los usuarios de la base de datos se mueven con la base de datos, pero es posible que los inicios de sesión de nivel de servidor coincidentes no existan en la nueva instancia. Esa falta de coincidencia produce usuarios huérfanos. La transferencia de inicios de sesión y contraseñas mantiene intacta la autenticación del usuario y evita interrupciones de inicio de sesión después de mover una base de datos.
Después de mover una base de datos de una instancia de SQL Server en el servidor A a una instancia de SQL Server en el servidor B, es posible que los usuarios no puedan iniciar sesión en el servidor de bases de datos en el servidor B. Además, es posible que los usuarios reciban el siguiente mensaje de error:
Error de inicio de sesión del usuario "MiUsuario". (Microsoft SQL Server, Error: 18456)
Este problema se produce porque los inicios de sesión de la instancia de SQL Server en el servidor A no existen en la instancia de SQL Server en el servidor B.
El error 18456 también puede producirse por otros motivos. Para obtener más información sobre las diversas causas y sus resoluciones, consulte MSSQLSERVER_18456.
Métodos para transferir inicios de sesión entre instancias de SQL Server
Para transferir inicios de sesión, use uno de los métodos siguientes, según corresponda para su situación.
Generación de scripts de inicio de sesión en SSMS y restablecimiento de contraseñas en el destino
Puede generar scripts de inicio de sesión en SQL Server Management Studio (SSMS) mediante la opción Generar scripts para una base de datos.
Para generar scripts a través de SSMS en el servidor de origen y restablecer manualmente contraseñas para inicios de sesión de SQL Server en el servidor de destino, siga estos pasos:
Conéctese al servidor A que hospeda el servidor SQL Server de origen.
Expanda el nodo Bases de datos .
Seleccione y mantenga pulsada (o haga clic con el botón derecho sobre) cualquier base de datos de usuario y, a continuación, seleccione Tareas>Generar scripts.
Se abre la página Introducción. Seleccione Siguiente para abrir la página Elegir objetos . Seleccione Crear un script a partir de toda la base de datos y todos los objetos de esta.
Seleccione Siguiente para abrir la página Establecer opciones de scripting.
Seleccione el botón Avanzadas para las opciones de inicio de sesión del script.
En la lista Avanzadas, busque Inicios de sesión de scripts, configure la opción como True y seleccione OK.
Vuelva a Establecer opciones de scripting, en Seleccionar cómo se deben guardar los scripts , seleccione Abrir en la nueva ventana de consulta.
Seleccione Siguiente dos veces y, a continuación, seleccione Finalizar.
Busque la sección en el script que contiene inicios de sesión. Normalmente, el script generado contiene texto con el siguiente comentario al principio de esta sección:
/* For security reasons the login is created disabled and with a random password. */Nota:
Este comentario indica que los inicios de sesión de autenticación de SQL Server se generan con una contraseña aleatoria y están deshabilitados de forma predeterminada. Debe restablecer la contraseña y volver a habilitar estos inicios de sesión en el servidor de destino.
Aplique el script de inicio de sesión desde el script generado más grande al servidor SQL Server de destino.
Para los inicios de sesión de autenticación de SQL Server, restablezca la contraseña en el servidor SQL Server de destino y vuelva a habilitar esos inicios de sesión.
Transferencia de inicios de sesión y contraseñas mediante sp_help_revlogin
Cree procedimientos almacenados que ayuden a generar los necesarios scripts para transferir credenciales y sus contraseñas. Para ello, conéctese al servidor A mediante SQL Server Management Studio (SSMS) o cualquier otra herramienta cliente y ejecute el siguiente script:
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 ENDNota:
Este script crea dos procedimientos almacenados en la base de datos maestra. Los procedimientos se denominan sp_hexadecimal y sp_help_revlogin.
En el editor de consultas de SSMS, seleccione la opción Resultados en texto .
Ejecute la siguiente instrucción en la misma ventana de consulta o en otra diferente:
EXEC sp_help_revloginEl script de salida que genera el procedimiento almacenado
sp_help_revlogines el script de inicio de sesión. Este script de inicio de sesión crea los inicios de sesión que contienen el identificador de seguridad (SID) y la contraseña originales.Revise y siga la información de la sección Consideraciones adicionales al transferir inicios de sesión de SQL Server antes de continuar con los pasos de implementación en el servidor de destino.
Una vez completados los pasos aplicables de la sección Consideraciones adicionales al transferir SQL Server inicios de sesión, conéctese al servidor de destino B mediante cualquier herramienta de cliente (como SSMS).
Ejecute el script generado como resultado de
sp_helprevlogindesde el servidor A.
Consideraciones adicionales al transferir inicios de sesión de SQL Server
Revise la siguiente información antes de ejecutar el script de salida en la instancia del servidor B:
Comprender el hash de contraseñas en traspasos de inicios de sesión de SQL Server
SQL Server aplica funciones hash a las contraseñas de las siguientes maneras:
-
VERSION_SHA1: usa el algoritmo SHA1. SQL Server 2000 hasta SQL Server 2008 R2 usan este hash. Estas versiones están fuera de la compatibilidad estándar y extendida, por lo que debe encontrarVERSION_SHA1hashes solo al migrar de instancias heredadas. -
VERSION_SHA2: usa el algoritmo SHA2-512. SQL Server 2012 y versiones posteriores, incluidas las versiones admitidas actualmente, usan este hash.
El script de salida crea los inicios de sesión mediante la contraseña cifrada. El HASHED argumento de la instrucción CREATE LOGIN provoca este comportamiento. Este argumento indica que la contraseña especificada después del argumento PASSWORD ya está hasheada.
Controlar los cambios de dominio durante las transferencias de inicio de sesión de SQL Server
Si los servidores de origen y destino están en dominios diferentes, revise cuidadosamente el script de salida. Cambie el script para reemplazar el nombre de dominio original por el nuevo nombre de dominio en las CREATE LOGIN instrucciones . Los inicios de sesión integrados concedidos al nuevo dominio no comparten el mismo SID que los inicios de sesión en el dominio original, por lo que los usuarios se vuelven huérfanos de estos inicios de sesión. Para corregir usuarios huérfanos, consulte Solución de problemas de usuarios huérfanos (SQL Server) y ALTER USER.
Si el servidor A y el servidor B están en el mismo dominio, se usa el mismo SID. Por lo tanto, los usuarios no están huérfanos.
Permisos necesarios para ver y seleccionar inicios de sesión de SQL Server
De forma predeterminada, solo los miembros del rol fijo de servidor sysadmin pueden ejecutar una instrucción SELECT sobre la vista sys.server_principals. A menos que un administrador del sistema conceda los permisos necesarios a otros usuarios, esos usuarios no pueden crear ni ejecutar el script de salida.
La configuración predeterminada de la base de datos no se convierte en script ni se transfiere
Los pasos de este artículo no transfieren la información de base de datos predeterminada para un inicio de sesión determinado. Esta limitación existe porque es posible que la base de datos predeterminada no exista siempre en el servidor B. Para definir la base de datos predeterminada para un inicio de sesión, use la instrucción ALTER LOGIN pasando el nombre de inicio de sesión y la base de datos predeterminada como argumentos.
Administrar las diferencias en el orden de clasificación durante las transferencias de inicios de sesión en SQL Server
Los servidores de origen y destino pueden tener diferentes órdenes de ordenación o pueden usar el mismo criterio de ordenación. Este es el modo en que puede abordar cada escenario:
Servidor A insensible a mayúsculas y servidor B sensible a mayúsculas: el criterio de ordenación del servidor A es insensible a mayúsculas y el criterio de ordenación del servidor B es sensible a mayúsculas. En este caso, los usuarios deben escribir todas las letras de las contraseñas en mayúsculas una vez que se hayan transferido los inicios de sesión y las contraseñas a la instancia del servidor B.
Servidor sensible a mayúsculas A y servidor insensible a mayúsculas B: El criterio de ordenación del servidor A es sensible a mayúsculas, y el criterio de ordenación del servidor B es insensible a mayúsculas. En este caso, los usuarios no pueden iniciar sesión con los inicios de sesión y las contraseñas que se transfieren a la instancia en el servidor B a menos que se cumpla una de las condiciones siguientes:
- Las contraseñas originales no contienen letras.
- Todas las letras de las contraseñas originales son mayúsculas.
Distingue entre mayúsculas y minúsculas o no distingue entre mayúsculas y minúsculas en ambos servidores: el criterio de ordenación del servidor A y del servidor B distingue entre mayúsculas y minúsculas, o el criterio de ordenación del servidor A y del servidor B no distingue entre mayúsculas y minúsculas. En estos casos, los usuarios no experimentan un problema.
Corrección de conflictos con inicios de sesión existentes en el servidor de destino
El script comprueba si el inicio de sesión existe en el servidor de destino y crea un inicio de sesión solo si no existe. Sin embargo, si recibe el siguiente mensaje de error al ejecutar el script de salida en la instancia del servidor B, debe resolver manualmente el conflicto siguiendo los pasos de esta sección.
Msj 15025, Nivel 16, Estado 1, Línea 1
La entidad de seguridad de servidor 'MyLogin' ya existe.
Del mismo modo, un inicio de sesión que ya está en la instancia del servidor B podría tener un SID que sea el mismo que un SID en el script de salida. En este caso, recibirá el mensaje de error siguiente al ejecutar el script de salida en la instancia del servidor B:
Msj 15433, Nivel 16, Estado 1, Línea 1 El parámetro sid proporcionado está en uso.
Para corregir el conflicto manualmente, siga estos pasos:
- Revise atentamente el script de salida.
- Examine el contenido de la
sys.server_principalsvista en la instancia del servidor B. - Realice la acción adecuada para cada error, como quitar o cambiar el nombre del inicio de sesión en conflicto en el servidor B o quitar la instrucción duplicada
CREATE LOGINdel script de salida antes de volver a ejecutarlo.
En SQL Server, el SID de un inicio de sesión rige el acceso de nivel de base de datos. Un inicio de sesión puede tener diferentes SID cuando se asigna a los usuarios de distintas bases de datos, lo que puede ocurrir si combina manualmente bases de datos de distintos servidores. En ese caso, el inicio de sesión solo podrá usar la base de datos en la que el SID de la entidad de seguridad de la base de datos coincida con el SID en la vista sys.server_principals. Para solucionar este problema, quite el usuario de la base de datos que tiene el SID no coincidente mediante la instrucción DROP USER . A continuación, vuelva a agregar el usuario con la instrucción CREATE USER y asócielo al inicio de sesión correcto (elemento de seguridad del servidor).
Para obtener más información sobre las entidades de seguridad de servidor y base de datos, vea CREATE USER y CREATE LOGIN.
Escenarios avanzados y solución de problemas
Si sigue viendo errores de inicio de sesión después de transferir inicios de sesión, compruebe los siguientes elementos:
-
Usuarios huérfanos de la base de datos: ejecute
sys.sp_change_users_login(heredado) o useALTER USER ... WITH LOGIN = ...para reasociar los usuarios de la base de datos con los inicios de sesión transferidos. Para obtener más información, consulte Solucionar problemas de usuarios huérfanos (SQL Server). -
Bases de datos contenidas: la propia base de datos almacena los inicios de sesión de los usuarios de una base de datos contenida, por lo que se mueven con ella. No es necesario transferir esos usuarios mediante
sp_help_revlogin. - Grupos de disponibilidad Always On e instancias de clúster de conmutación por error: Transfiera los inicios de sesión a cada réplica o nodo para que los usuarios puedan iniciar sesión después de una conmutación por error. Para obtener más información, consulte Administración de inicios de sesión para trabajos mediante bases de datos en un grupo de disponibilidad AlwaysOn.
- Azure SQL Managed Instance y Azure SQL Database: la transferencia de inicio de sesión funciona de forma diferente en Azure. Consulte Migración de inicios de sesión entre SQL Server y SQL Managed Instance y Administrar inicios de sesión y usuarios en Azure SQL Database.
- Error de inicio de sesión 18456: Para otras causas y soluciones, consulta MSSQLSERVER_18456.