2. 身份验证模式与登录名管理

SQL Server 的安全边界从“谁能连上实例”开始,而这一步由身份验证模式决定。实例级有两种验证方式:Windows 身份验证和SQL Server 身份验证。前者依赖 Windows 令牌,由操作系统完成凭据校验,SQL Server 只接收已认证的身份;后者由 SQL Server 自己保存登录名和密码哈希,并在连接时校验。两者可以同时启用,形成“混合模式”。理解它们的差异,是后续登录名、密码策略与审计配置的基础。

两种模式的工作路径

Windows 身份验证下,客户端先向 Windows 证明自己(域登录或本地登录),SQL Server 收到的是已通过 Kerberos 或 NTLM 验证的令牌,因此不需要在实例内保存密码。SQL Server 身份验证下,客户端把登录名和密码发给实例,实例比对 sys.sql_logins 中的密码哈希(SQL Server 2012 起使用 SHA-512 加盐),成功后才建立会话。混合模式同时接受两类请求,但 Windows 身份验证始终优先尝试。

SQL Server 身份验证路径与登录名解析 客户端连接请求 SSMS / 应用 / sqlcmd Windows 身份验证 Windows 令牌 / Kerberos 实例内不保存密码 → 映射到登录名 SQL Server 身份验证 登录名 + 密码 比对密码哈希(SHA-512) → 校验策略与状态 登录名 (Login) 实例级安全主体 默认架构 / 状态 数据库用户 映射到登录名 获得库内权限 密码策略 CHECK_POLICY / 过期 锁定阈值 / 复杂度 登录审计 成功 / 失败登录 错误 18456 状态码

配置身份验证模式

模式在实例级别设置,修改后必须重启 SQL Server 服务才生效。图形界面路径为:SSMS 中右键实例 → 属性 → 安全性 → 选择“Windows 身份验证模式”或“SQL Server 和 Windows 身份验证模式(混合模式)”。脚本方式可用 xp_instance_regwrite 修改注册表,或通过 ALTER LOGIN 调整单个登录名状态。生产环境建议默认保持 Windows 身份验证,仅在应用确实需要独立账号时才启用混合模式,并配合强密码策略。

-- 查看当前实例的验证模式(1=仅Windows,2=混合)
EXEC xp_instance_regread
  N'HKEY_LOCAL_MACHINE',
  N'Software\Microsoft\MSSQLServer\MSSQLServer',
  N'LoginMode';

-- 启用混合模式(需重启服务)
EXEC xp_instance_regwrite
  N'HKEY_LOCAL_MACHINE',
  N'Software\Microsoft\MSSQLServer\MSSQLServer',
  N'LoginMode', REG_DWORD, 2;

创建登录名与密码策略

创建 SQL 登录名时,密码策略由 CHECK_POLICY 和 CHECK_EXPIRATION 控制。开启 CHECK_POLICY 后,SQL Server 会调用 Windows 的密码策略:强制复杂度(大写、小写、数字、符号中至少三类)、最小长度、历史记录和锁定阈值。开启 CHECK_EXPIRATION 后,密码到期会要求用户改密。对服务账号或应用账号,若无法交互改密,可显式关闭过期检查,但应通过其他方式轮换密钥。

-- 创建带密码策略的 SQL 登录名
CREATE LOGIN app_reader
  WITH PASSWORD = N'R3ad@2024!Sql',
       CHECK_POLICY = ON,
       CHECK_EXPIRATION = ON,
       DEFAULT_DATABASE = SalesDB;

-- 创建 Windows 登录名(域账号)
CREATE LOGIN [CORP\svc_report]
  FROM WINDOWS
  WITH DEFAULT_DATABASE = SalesDB;

-- 修改登录名状态与密码
ALTER LOGIN app_reader WITH PASSWORD = N'N3w@2024!Sql';
ALTER LOGIN app_reader DISABLE;   -- 临时禁用
ALTER LOGIN app_reader ENABLE;

创建后可用 sys.sql_logins 和 sys.server_principals 查看登录名属性,包括 is_policy_checked、is_expiration_checked、is_disabled 等字段。注意:登录名只是实例级入口,要访问具体数据库,还需在目标库中创建对应用户并授予权限,否则连接成功也会在访问对象时被拒绝。

登录审计与故障排查

登录失败最常见的错误是 18456,其状态码能快速定位原因。例如状态 5 表示登录名不存在,状态 7 表示密码错误且登录名存在,状态 8 表示密码错误,状态 18 表示密码已过期必须修改,状态 38 表示数据库不存在,状态 40 表示登录名被禁用。排查时应先看错误状态码,再核对登录名是否存在、是否启用、密码是否过期、默认数据库是否可访问。

状态码含义处理方向
5登录名不存在确认实例名与登录名拼写,检查是否连错实例
7 / 8密码错误重置密码,检查大小写与特殊字符
18密码已过期修改密码或关闭过期检查
38默认数据库不存在修改默认数据库或恢复该库
40登录名被禁用执行 ALTER LOGIN ... ENABLE

审计方面,可通过 SQL Server 审核(Server Audit)记录成功和失败的登录,也可用登录触发器把登录事件写入日志表。轻量场景下,直接读取错误日志即可:EXEC xp_readerrorlog 0, 1, N'登录失败' 能筛出失败记录。若需长期留存,建议配置审核到文件或 Windows 事件日志,并定期归档。

排查顺序建议:先看错误状态码 → 确认登录名存在且启用 → 检查密码策略与过期 → 核对默认数据库 → 最后检查网络与实例名。多数“连不上”问题在前两步即可定位。
混合模式下,sa 账户是攻击重点。应重命名或禁用 sa,并确保其密码符合策略;同时避免应用直接使用 sa 连接。启用混合模式后,务必对 SQL 登录名开启 CHECK_POLICY,否则弱密码会直接暴露实例入口。