DBAtlas · 数据库运维图谱

查找孤立用户并重新映射到登录名(还原/AG 之后)

SQL Server安全

命令

USE [Musteri];
-- Database users without a matching login:
SELECT dp.name AS user_name, dp.type_desc, dp.authentication_type_desc, dp.sid, dp.create_date
FROM   sys.database_principals dp
  LEFT JOIN sys.server_principals sp ON sp.sid = dp.sid
WHERE  sp.sid IS NULL
  AND  dp.type IN ('S', 'U', 'G')
  AND  dp.authentication_type_desc IN (N'INSTANCE', N'WINDOWS')
  AND  dp.principal_id > 4;

-- If a login with the same name exists, remap the SID:
ALTER USER [app_user] WITH LOGIN = [app_user];

-- Permanent fix: generate CREATE LOGIN with SID + password hash on the source, run it on the target:
SELECT N'CREATE LOGIN ' + QUOTENAME(sp.name)
     + N' WITH PASSWORD = ' + CONVERT(NVARCHAR(MAX), LOGINPROPERTY(sp.name, 'PasswordHash'), 1)
     + N' HASHED, SID = ' + CONVERT(NVARCHAR(MAX), sp.sid, 1)
     + N', CHECK_POLICY = OFF;' AS create_login_stmt
FROM   sys.server_principals sp
WHERE  sp.type = 'S' AND sp.name = N'app_user';

作用

找出 SID 与任何服务器登录名都不匹配的数据库用户(孤立用户);将用户重新映射到现有登录名,并生成脚本以相同 SID 和密码哈希在另一台服务器上重建登录名。

适用场景

在另一台服务器上还原/附加数据库后、AG/日志传送故障转移后应用收到“Login failed for user”时,或服务器迁移期间。

注意

ALTER USER ... WITH LOGIN 会把用户的 SID 改为登录名的 SID;在 AG 中此更改从主副本流向辅助副本,但若辅助服务器上登录名的 SID 不同,下次故障转移时问题会重现。永久解决办法是在每个副本上用相同 SID 创建登录名。密码哈希是敏感信息;请安全保存脚本。包含数据库用户(authentication_type = DATABASE)不需要登录名,不会被列出。

在 DBAtlas 中打开 →

相关内容