sql >> Base de Datos >  >> RDS >> Database

Cómo funcionan los inicios de sesión en servidores vinculados (ejemplos de T-SQL)

Al configurar un servidor vinculado en SQL Server, configurar los inicios de sesión a veces puede ser confuso. En este artículo, mi objetivo es proporcionar una descripción general de alto nivel de cómo SQL Server asigna inicios de sesión locales a inicios de sesión remotos en el servidor vinculado.

Cuando usa sp_addlinkedserver para crear un servidor vinculado en SQL Server, se crea automáticamente una asignación predeterminada entre todos los inicios de sesión en el servidor local y los inicios de sesión remotos en el servidor vinculado. SQL Server usa las credenciales del inicio de sesión local cuando se conecta al servidor vinculado en nombre del inicio de sesión.

Entonces, si su inicio de sesión local tiene un inicio de sesión correspondiente en el servidor vinculado, con las mismas credenciales y tiene los permisos apropiados, podrá conectarse usando su inicio de sesión local. No es necesario agregar un inicio de sesión para el servidor vinculado (suponiendo que esté feliz de conectarse usando su propio inicio de sesión local).

Pero si su inicio de sesión local no tiene un inicio de sesión correspondiente en el servidor vinculado (y con las mismas credenciales), la conexión fallará.

En tales casos, puede usar sp_addlinkedsrvlogin para crear un inicio de sesión para el servidor vinculado para que los inicios de sesión locales puedan conectarse al servidor vinculado incluso cuando no tengan un inicio de sesión correspondiente en el servidor vinculado.

Hacer esto puede resultar en que se utilicen diferentes usuarios en el servidor vinculado, dependiendo de si tienen o no un inicio de sesión correspondiente en el servidor vinculado.

Para los usuarios conectados a SQL Server mediante el modo de autenticación de Windows, SQL Server puede usar automáticamente las credenciales de seguridad de Windows siempre que la delegación de la cuenta de seguridad esté disponible en el cliente y el servidor de envío, y el proveedor admita el modo de autenticación de Windows.

Los ejemplos de esta página utilizan inicios de sesión de SQL Server (no utilizan el modo de autenticación de Windows). Estos ejemplos muestran los resultados que obtengo al iniciar sesión en un servidor vinculado en diferentes escenarios utilizando inicios de sesión locales de SQL Server.

Ejemplo 1:servidor vinculado sin inicio de sesión explícito

Primero crearé un servidor vinculado llamado Homer, pero no crearé ningún inicio de sesión asociado.

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

Esto crea automáticamente una asignación predeterminada entre todos los inicios de sesión en el servidor local y los inicios de sesión remotos en el servidor vinculado.

Ahora intentaré ejecutar la siguiente consulta de transferencia en el servidor vinculado utilizando varios inicios de sesión locales:

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

Los resultados de la consulta son los siguientes.

sa

Login failed for user 'sa'.

Información de inicio de sesión :Hay un inicio de sesión llamado 'sa' en ambos servidores, pero tienen diferentes contraseñas. Ambos son miembros del sysadmin rol de servidor.

Lisa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'Lisa' en ambos servidores y tienen la misma contraseña. Ambos son miembros del sysadmin rol de servidor

Milhouse

Login failed for user 'Milhouse'.

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Apu

Login failed for user 'Apu'.

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Ejemplo 2:agregar un inicio de sesión para el servidor vinculado

A continuación, crearé un inicio de sesión para el servidor vinculado.

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

Este inicio de sesión se corresponde con un inicio de sesión en el servidor remoto, por lo que se crea una asignación entre ellos.

Ahora cada usuario volverá a ejecutar la siguiente consulta:

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

Los resultados de la consulta son los siguientes.

sa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'sa' en ambos servidores, pero tienen diferentes contraseñas. Ambos son miembros del sysadmin rol de servidor.

Lisa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'Lisa' en ambos servidores y tienen la misma contraseña. Ambos son miembros del sysadmin rol de servidor

Milhouse

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

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Apu

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

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Entonces, todos los inicios de sesión locales pudieron conectarse al servidor vinculado. Incluso los inicios de sesión que no tienen un inicio de sesión remoto correspondiente en el servidor vinculado pudieron conectarse. Esto se debe a que todos usaron el inicio de sesión de Maggie. ¡Gracias Maggie!

Ejemplo 3:restringir el inicio de sesión

Ahora actualizaré el inicio de sesión del servidor vinculado para que esté restringido a Milhouse.

Pero para hacer esto, tendré que eliminar el servidor vinculado y volver a crearlo. Si no hago esto, SQL Server usará las asignaciones existentes y obtendré los mismos resultados que arriba.

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';

Así que en este caso uso @locallogin='Milhouse' (en lugar de @locallogin=NULL como en el ejemplo anterior). Esto agregará una asignación de inicio de sesión para un solo inicio de sesión local (Milhouse).

Cada usuario vuelve a ejecutar la siguiente consulta:

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

Los resultados de la consulta son los siguientes.

sa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'sa' en ambos servidores, pero tienen diferentes contraseñas. Ambos son miembros del sysadmin rol de servidor.

Lisa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'Lisa' en ambos servidores y tienen la misma contraseña. Ambos son miembros del sysadmin rol de servidor

Milhouse

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

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Apu

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

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Entonces, la conclusión clave aquí es que, incluso cuando restringe el inicio de sesión a un solo inicio de sesión local, no impide que otros inicios de sesión locales se conecten al servidor vinculado. Si tienen un inicio de sesión correspondiente en el servidor vinculado, podrán acceder a él utilizando su propia asignación de inicio de sesión que se creó cuando sp_addlinkedserver fue ejecutado.

Ejemplo 4:en realidad restringirlo a un solo inicio de sesión

Si realmente solo desea restringirlo a un solo inicio de sesión y no más, puede usar sp_droplinkedsrvlogin para eliminar todas las asignaciones de inicio de sesión que sp_addlinkedserver crea antes de ejecutar 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';

Ahora ejecutemos la consulta una vez más con cada inicio de sesión:

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

Los resultados de la consulta son los siguientes.

sa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'sa' en ambos servidores, pero tienen diferentes contraseñas. Ambos son miembros del sysadmin rol de servidor.

Lisa

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

Información de inicio de sesión :Hay un inicio de sesión llamado 'Lisa' en ambos servidores y tienen la misma contraseña. Ambos son miembros del sysadmin rol de servidor

Milhouse

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

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Apu

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

Información de inicio de sesión :Este inicio de sesión solo está en el servidor local. No hay un inicio de sesión correspondiente en el servidor vinculado.

Configuración del Login Remoto

Conectarse con éxito al servidor vinculado es solo el primer paso del proceso. Una vez conectado, su capacidad para hacer cosas se verá afectada por los permisos del usuario remoto al que está asignado su inicio de sesión.

Por ejemplo, si Maggie se creó en el servidor remoto de esta manera:

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

USE Music;
CREATE USER Maggie FOR LOGIN Maggie;

GRANT SELECT ON DATABASE::Music TO Maggie;

Todo lo que puede hacer es ejecutar SELECT declaraciones contra la base de datos 'Música'. Por lo tanto, cualquiera que se conecte al servidor vinculado utilizando el inicio de sesión de Maggie se limitará a eso.

Es una buena práctica otorgar solo los permisos que se requieren, pero no más.

Documentación Oficial

Este artículo tenía como objetivo proporcionar una descripción general de alto nivel de cómo funcionan los inicios de sesión con servidores vinculados. Hay muchos otros escenarios que no cubrí aquí.

Si está interesado en obtener más información, consulte los siguientes enlaces a la documentación de Microsoft:

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