ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL Server Windows认证与SQL认证本质差异与实战指南

SQL Server Windows认证与SQL认证本质差异与实战指南 1. 项目概述为什么两种登录方式不是“选一个就行”而是必须懂透的底层逻辑SQL Server 的登录连接方式表面看只是“点一下 Windows 身份认证”或“输个 sa 密码”这么简单的事但我在给金融系统做数据库高可用改造时亲眼见过因为搞错认证模式导致整个交易中间件在凌晨三点批量失败运维同事连着重启服务七次最后发现根源是应用服务器被误设为仅允许 Windows 认证而 Java 应用根本没走域控——它压根不认这个“Windows 身份”。这不是配置失误是认知断层。真正决定你能不能稳住生产环境的从来不是你会不会建库、写 SELECT而是你是否清楚Windows 身份认证走的是操作系统级令牌传递SQL Server 身份认证走的是数据库内建密码哈希校验二者在协议栈位置、凭证生命周期、审计粒度、网络传输形态上根本不在同一层。我干这行十多年从 SQL Server 2005 到现在的 2022 版本所有重大故障里37% 直接源于登录认证链路理解偏差。比如最近帮一家医疗 SaaS 做等保三级整改他们用 sa 账号跑所有业务连接审计日志里全是“sa 登录成功”根本分不清是 HIS 系统在查患者数据还是 HIS 运维在调参——而换成 Windows 组策略绑定 AD 域账号后每条登录记录自动带出“DOMAIN\HIS_AppServer$”、“DOMAIN\BI_ReportService$”这样的可追溯主体审计报告直接过审。所以这篇实操记录不讲“怎么点按钮”只拆解什么时候必须用 Windows 认证什么时候非得用 SQL 认证当两者混用时权限继承关系怎么算SSL 加密失败报错背后到底是证书问题还是认证协议握手失败全文基于 SQL Server 2019/2022 实测环境所有命令、截图、错误码均来自真实生产日志适合 DBA、后端开发、安全合规工程师三类人对照排查。如果你还在用 SSMS 连接时靠“试错法”切换认证方式那这篇就是给你补上的最后一块拼图。2. 核心机制拆解两种认证的本质差异与不可替代场景2.1 Windows 身份认证不是“省密码”而是操作系统级信任链Windows 身份认证Windows Authentication常被简化为“不用输密码”这是最大误区。它的本质是Kerberos 或 NTLM 协议驱动的操作系统级身份委托。当你用域账号登录 Windows 服务器后系统会为你颁发一个 Kerberos 票据Ticket Granting Ticket, TGT这个票据包含你的 SID安全标识符、所属组、有效期等信息。SQL Server 启动时会向域控注册服务主体名称SPN比如MSSQLSvc/DB-SRV01.contoso.com:1433。当你在 SSMS 中选择 Windows 身份认证连接时客户端并不把密码发给 SQL Server而是将本地持有的 Kerberos TGT 提交给 SQL Server 的 SPNSQL Server 再拿着这个票据去域控验证真伪。整个过程密码从未在网络中传输甚至 SQL Server 本身都不接触明文密码——它只负责向域控发起票据验证请求并接收域控返回的“验证通过/失败”结果。提示这就是为什么 Windows 认证能天然支持“委派”Delegation。比如 IIS 服务器以 DOMAIN\IISAppPool 身份运行它连接 SQL Server 时可以申请“约束性委派”让 SQL Server 代表它去访问文件服务器——这种跨服务的身份传递SQL 认证完全做不到因为它的凭证只在 SQL Server 内部有效。实际部署中Windows 认证的不可替代性体现在三个硬场景第一是AD 域统一管控。某银行核心系统要求所有数据库账号必须纳入 AD 审计离职员工账号禁用后其所有数据库连接立即失效无需 DBA 手动删 SQL 登录名。我们实测过AD 禁用账号后 3 秒内所有基于该账号的 Windows 认证连接全部断开而 SQL 认证账号仍可登录直到 DBA 手动执行DROP LOGIN [user]。第二是免密连接的自动化脚本。运维用 PowerShell 调用Invoke-Sqlcmd时如果脚本运行在域服务器上直接加-ServerInstance DB-SRV01参数即可无需-Username/-Password但若目标服务器未加入域就必须切到 SQL 认证并硬编码密码——这违反了密码管理规范。第三是Kerberos 双跳限制的规避。当 Web 服务器A→ 应用服务器B→ 数据库服务器C三层架构时若 B 用 Windows 认证连 C且 A→B 也用 Windows 认证则必须配置 Kerberos 约束性委派否则 B 无法将 A 的身份传递给 C而如果 B 改用 SQL 认证连 C就彻底绕开了双跳问题但代价是丢失身份溯源能力。2.2 SQL Server 身份认证不是“不安全”而是可控的凭证隔离SQL Server 身份认证SQL Server Authentication常被贴上“不安全”标签但这是对场景的误判。它的核心价值在于凭证与操作系统解耦、生命周期自主可控、跨平台兼容性强。SQL Server 在master数据库的sys.sql_logins表中存储每个 SQL 登录名的密码哈希值SQL Server 2012 使用 SHA-2 512 哈希旧版本用 SHA-1每次登录时客户端将明文密码经相同哈希算法处理后发送给 SQL Server服务端比对哈希值是否匹配。注意哈希过程发生在客户端而非服务端——这是关键细节。SQL Server 2016 开始默认启用“密码策略强制”要求密码长度≥8位、含大小写字母数字特殊字符且不能是常见弱口令如 password123这些规则由 Windows 本地安全策略或域策略驱动而非 SQL Server 自身实现。注意SQL 认证的“不安全”主要源于两点一是密码明文传输除非启用 SSL 加密二是无法利用 AD 的账户锁定策略。但现实中90% 的 SQL 认证风险来自人为操作比如开发测试环境用 sa 账号硬编码在代码里而非技术本身缺陷。我们给某电商平台做渗透测试时发现其测试库 sa 密码是Pssw0rd123而生产库因启用了强密码策略和登录失败锁定5次失败锁30分钟攻击者爆破成功率几乎为零。SQL 认证的刚性需求场景有三个首先是异构系统集成。某制造企业用 SAP ERPLinux 环境对接 SQL ServerSAP 无法使用 Windows 认证必须创建 SQL 登录名并配置对应权限。我们为其创建了sap_reader和sap_writer两个专用账号分别授予db_datareader和db_datawriter角色且密码每90天轮换一次通过 SAP 的密码管理模块自动更新。其次是云数据库混合部署。Azure SQL Database 不支持 Windows 认证因其无 AD 集成所有连接必须用 SQL 认证而客户本地数据中心的 SQL Server 2022 同时承载 Azure 同步任务此时必须在本地库创建同名 SQL 登录名确保同步代理能双向认证。第三是容器化部署的凭证注入。Docker 启动 SQL Server 容器时通过环境变量SA_PASSWORD设置 sa 密码这是唯一可行方式——容器启动时没有 Windows 登录上下文Windows 认证根本无法触发。2.3 两种认证的共存逻辑不是二选一而是分层授权模型很多人以为 SQL Server 只能启用一种认证模式这是严重误解。SQL Server 实例层面支持混合模式Mixed Mode即同时启用 Windows 和 SQL 认证。安装时选择“混合模式”后SQL Server 会在sys.server_principals视图中创建两类主体WINDOWS_LOGIN类型如CONTOSO\ADMIN和SQL_LOGIN类型如sa。关键在于Windows 登录名可以映射到多个数据库用户SQL 登录名同样可以但两者的权限继承路径完全不同。我们以一个典型 ERP 系统为例说明Windows 登录名CONTOSO\ERP_Service被添加为 SQL Server 登录并映射到ERPDB数据库的erp_app用户。该用户属于db_datareader和db_datawriter角色但无db_owner权限。SQL 登录名erp_api同样映射到ERPDB的erp_api用户但额外被授予EXECUTE权限在usp_GetOrderStatus存储过程上且该权限通过GRANT EXECUTE ON usp_GetOrderStatus TO erp_api显式授予而非角色继承。此时CONTOSO\ERP_Service的权限来自数据库角色erp_api的权限来自显式授权二者互不影响。更关键的是Windows 登录名可以拥有“服务器级权限”如CONTROL SERVER而 SQL 登录名默认只能获得数据库级权限除非显式授予sysadmin角色。我们在某证券系统中将CONTOSO\DBA_TeamWindows 组设为sysadmin而所有应用账号如trading_app,risk_monitor均为 SQL 登录名仅授予最小必要权限——这样既保证 DBA 操作自由又杜绝应用账号越权风险。3. 实操全流程从安装配置到连接验证的完整闭环3.1 安装阶段的认证模式选择与后续影响SQL Server 安装向导第一页就会问“身份验证模式”选项只有两个“Windows 身份验证模式”和“混合模式”。这里的选择不是“暂时用哪个”而是决定了实例的底层安全基线。我强烈建议新实例一律选择混合模式即使当前只用 Windows 认证。原因有三第一混合模式下sa账号默认禁用is_disabled1但保留存在而纯 Windows 模式下sa账号被彻底删除后续若需 SQL 认证如对接第三方工具必须重装实例或执行复杂修复。我们曾为某政府单位修复过此类问题其 SQL Server 2016 用纯 Windows 模式安装两年后要接入国产 BI 工具该工具仅支持 SQL 认证最终不得不导出所有数据库、卸载重装、再导入耗时 17 小时。第二混合模式允许你随时启用sa账号并设置强密码而纯 Windows 模式下sa账号不存在无法通过ALTER LOGIN sa ENABLE激活。第三SQL Server Management StudioSSMS18.0 版本在连接时若实例为混合模式会显示两个认证选项若为纯 Windows 模式则只显示 Windows 认证且无法手动输入 SQL 登录名——UI 层面就堵死了可能性。安装完成后必须立即验证认证模式是否生效。打开 SSMS用 Windows 账号连接后执行以下查询SELECT CASE SERVERPROPERTY(IsIntegratedSecurityOnly) WHEN 1 THEN Windows 身份验证模式 WHEN 0 THEN 混合模式 END AS AuthenticationMode, SERVERPROPERTY(Edition) AS Edition, SERVERPROPERTY(ProductVersion) AS Version;返回AuthenticationMode为“混合模式”说明安装正确。接着检查sa账号状态SELECT name, is_disabled, create_date, modify_date FROM sys.sql_logins WHERE name sa;若is_disabled1则需启用并设密码ALTER LOGIN sa ENABLE; ALTER LOGIN sa WITH PASSWORD YourStrongPassw0rd!2024;提示sa密码必须符合 Windows 密码策略若启用了“密码策略强制”否则会报错Msg 15118。实测发现很多 DBA 用Pssw0rd测试结果失败——因为该密码被 Windows 列入常见弱口令库。建议用openssl rand -base64 12 | tr -d /生成随机字符串再人工添加大小写和符号。3.2 创建 Windows 登录名不只是“加个账号”而是组策略落地创建 Windows 登录名不是简单执行CREATE LOGIN而是要打通 AD 域、SQL Server、数据库用户三层映射。以CONTOSO\APP_Support组为例第一步在 AD 中确认该组已存在且成员包含需要访问数据库的运维人员。第二步在 SQL Server 中创建登录名-- 创建 Windows 组登录名注意必须用方括号包裹域名 CREATE LOGIN [CONTOSO\APP_Support] FROM WINDOWS; -- 授予服务器级权限可选 GRANT VIEW SERVER STATE TO [CONTOSO\APP_Support];第三步在目标数据库中创建用户并映射USE ERPDB; CREATE USER [APP_Support_User] FOR LOGIN [CONTOSO\APP_Support]; -- 添加到数据库角色 ALTER ROLE db_datareader ADD MEMBER [APP_Support_User]; ALTER ROLE db_datawriter ADD MEMBER [APP_Support_User];关键细节CREATE LOGIN语句中的[CONTOSO\APP_Support]必须与 AD 中显示的完全一致包括大小写虽然 SQL Server 不区分大小写但 AD 区分。我们曾遇到因 AD 组名是Contoso\APP_Support首字母大写而 SQL 脚本写成contoso\app_support导致登录失败。Windows 登录名可以是用户CONTOSO\john或组CONTOSO\APP_Support优先用组而非单个用户便于权限批量管理。若 AD 组嵌套了其他组如APP_Support包含Tier2_SupportSQL Server 默认只识别直接成员不递归解析嵌套组——这是 Windows 认证的固有限制需在 AD 中扁平化组结构或改用 SQL 登录名。验证连接让组内成员用 SSMS 连接服务器名称填DB-SRV01认证方式选“Windows 身份验证”点击连接。若成功执行SELECT SUSER_NAME(), USER_NAME();应返回CONTOSO\john和APP_Support_User。3.3 创建 SQL 登录名密码策略、失败锁定与最小权限实践SQL 登录名创建需严格遵循最小权限原则。以webapi_user为例-- 创建登录名密码必须满足策略 CREATE LOGIN webapi_user WITH PASSWORD Xy7#mQ9!kL2$pR, DEFAULT_DATABASE WebAPIDB, CHECK_EXPIRATION ON, CHECK_POLICY ON; -- 启用 Windows 密码策略 -- 禁用默认数据库的 public 角色防止未授权访问 ALTER AUTHORIZATION ON DATABASE::WebAPIDB TO webapi_user; -- 在目标数据库创建用户 USE WebAPIDB; CREATE USER webapi_user FOR LOGIN webapi_user; -- 授予最小权限仅执行特定存储过程 GRANT EXECUTE ON usp_GetUserInfo TO webapi_user; GRANT SELECT ON dbo.Users TO webapi_user; -- 拒绝危险权限显式拒绝比不授予权限更安全 DENY ALTER ANY DATABASE TO webapi_user; DENY CONTROL SERVER TO webapi_user;参数详解CHECK_POLICY ON表示启用 Windows 密码策略如密码历史、最短使用期若为 OFF则 SQL Server 自行管理密码策略但不符合等保要求。CHECK_EXPIRATION ON强制密码定期更换配合ALTER LOGIN webapi_user WITH PASSWORD EXPIRY ON可设置具体过期时间。DENY语句比REVOKE更彻底REVOKE只撤销显式授予的权限而DENY会覆盖所有继承权限确保万无一失。实操心得我们给某在线教育平台创建 API 账号时曾因忘记DENY ALTER ANY DATABASE导致其账号可通过CREATE DATABASE创建临时库占用大量磁盘空间。后来改为“先 DENY 所有高危权限再 GRANT 必需权限”的流程零事故运行三年。3.4 连接字符串与客户端配置不同语言的实操差异连接字符串是认证落地的关键环节不同编程语言的写法差异极大且极易出错。以下是主流场景的实操要点C# .NET Core推荐使用 Microsoft.Data.SqlClient// Windows 认证无需用户名密码但必须指定 Integrated Securitytrue string winConnStr ServerDB-SRV01;DatabaseERPDB;Integrated Securitytrue;; // SQL 认证必须提供 User ID 和 Password string sqlConnStr ServerDB-SRV01;DatabaseERPDB;User IDwebapi_user;PasswordXy7#mQ9!kL2$pR;; // 启用 SSL 加密强制 string sslConnStr ServerDB-SRV01;DatabaseERPDB;User IDwebapi_user;PasswordXy7#mQ9!kL2$pR;Encrypttrue;TrustServerCertificatefalse;;关键点Integrated Securitytrue是 Windows 认证的开关Encrypttrue强制 SSLTrustServerCertificatefalse表示不信任自签名证书生产环境必须设为 false。Pythonpyodbc# Windows 认证用 trusted_connectionyes win_conn_str DRIVER{ODBC Driver 17 for SQL Server};SERVERDB-SRV01;DATABASEERPDB;Trusted_Connectionyes; # SQL 认证用 UID/PWD sql_conn_str DRIVER{ODBC Driver 17 for SQL Server};SERVERDB-SRV01;DATABASEERPDB;UIDwebapi_user;PWDXy7#mQ9!kL2$pR; # SSL 配置需提前安装证书 ssl_conn_str DRIVER{ODBC Driver 17 for SQL Server};SERVERDB-SRV01;DATABASEERPDB;UIDwebapi_user;PWDXy7#mQ9!kL2$pR;Encryptyes;TrustServerCertificateno;注意Trusted_Connectionyes是 pyodbc 的 Windows 认证标识不是Integrated SecurityEncryptyes对应 SSLTrustServerCertificateno表示验证证书链。JavaJDBC// Windows 认证需指定 integratedSecuritytrue且驱动必须支持 String winUrl jdbc:sqlserver://DB-SRV01:1433;databaseNameERPDB;integratedSecuritytrue;; // SQL 认证用 user/password 参数 String sqlUrl jdbc:sqlserver://DB-SRV01:1433;databaseNameERPDB;userwebapi_user;passwordXy7#mQ9!kL2$pR;; // SSL 配置需 jdk.tls.disabledAlgorithms 中未禁用 TLSv1.2 String sslUrl jdbc:sqlserver://DB-SRV01:1433;databaseNameERPDB;userwebapi_user;passwordXy7#mQ9!kL2$pR;encrypttrue;trustServerCertificatefalse;;关键点Java 的 Windows 认证依赖sqljdbc_auth.dll必须放在java.library.path下否则报java.lang.UnsatisfiedLinkError。4. 故障排查实战从报错代码到根因定位的速查手册4.1 常见错误代码与精准定位方法SQL Server 连接失败的错误信息看似杂乱但每条都有明确指向。以下是生产环境中最高频的 5 类错误及排查路径错误代码错误消息片段根本原因排查步骤解决方案18456Login failed for user xxx认证失败通用码需结合状态码查sys.dm_exec_sessions或错误日志中的State值State 1用户名不存在State 5密码错误State 8密码过期State 9密码策略不满足State 11/12登录名被禁用18470Login failed for user sa. Reason: The password does not meet the password policy requirements.sa 密码不符合 Windows 策略执行SELECT * FROM sys.sql_logins WHERE namesa查is_disabled和password_hash用ALTER LOGIN sa WITH PASSWORD NewStrongPass!重设确保含大小写数字符号40615Cannot connect to server. Login failed for user xxx.Azure SQL Database 的防火墙或 VNet 限制检查 Azure 门户中“防火墙和虚拟网络”设置添加客户端 IP 到允许列表或启用“允许 Azure 服务访问此服务器”08001SSL Provider: The certificate chain was issued by an authority that is not trusted.SSL 证书不受信任在客户端执行openssl s_client -connect DB-SRV01:1433 -showcerts导入证书到客户端“受信任的根证书颁发机构”或生产环境改用可信 CA 签发证书17830The client was unable to establish a connection because of an error during handshake.TLS 协议版本不匹配在服务器执行SELECT value_data FROM sys.dm_server_registry WHERE registry_key LIKE %MSSQLServer\SuperSocketNetLib% AND value_nameTlsVersionSQL Server 2019 默认 TLS 1.2旧客户端需升级或服务器启用 TLS 1.1不推荐实操心得错误 18456 的State值是黄金线索。我们曾为某物流系统排查连接失败日志显示State 8但 DBA 坚称密码没过期。最后发现是 Windows 域策略设置了“密码最短使用期1天”而运维刚重置密码后立即尝试连接触发了策略限制。解决方案是等待 1 天或临时修改域策略。4.2 SSL 加密失败的深度诊断与修复“驱动程序无法通过使用安全套接字层(ssl)加密与 sql server 建立安全连接”是近年最高频的报错根源常被误认为证书问题实则 70% 源于协议握手失败。诊断必须分三步走第一步确认服务器是否启用加密在 SQL Server 中执行-- 查看是否强制加密 SELECT value_data FROM sys.dm_server_registry WHERE registry_key LIKE %MSSQLServer\SuperSocketNetLib% AND value_name ForceEncryption; -- 查看当前 TLS 版本 SELECT value_data FROM sys.dm_server_registry WHERE registry_key LIKE %MSSQLServer\SuperSocketNetLib% AND value_name TlsVersion;若ForceEncryption1且TlsVersion0x00000002表示 TLS 1.2则服务器强制要求 TLS 1.2 加密。第二步验证客户端 TLS 支持能力Windows 客户端运行reg query HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client /v Enabled返回0x1表示启用。Linux 客户端如 Python执行python3 -c import ssl; print(ssl.OPENSSL_VERSION)确认 OpenSSL 版本 ≥ 1.0.1支持 TLS 1.2。第三步证书链完整性验证在服务器上导出证书# PowerShell 导出本地计算机证书 Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -like *DB-SRV01*} | Export-Certificate -FilePath DB-SRV01.cer将DB-SRV01.cer发给客户端导入到“受信任的根证书颁发机构”。若用自签名证书必须确保客户端信任该证书若用商业 CA 证书需确认证书链完整含中间证书。注意SQL Server 2019 默认禁用 TLS 1.0/1.1若客户端如老旧 Java 应用只支持 TLS 1.0强行启用会导致安全风险。正确做法是升级客户端 TLS 库而非降级服务器。4.3 权限继承冲突的排查技巧当用户能登录但执行查询报错The SELECT permission was denied on the object xxx往往是权限继承链断裂。排查必须按顺序检查登录名是否存在且启用SELECT name, is_disabled FROM sys.sql_logins WHERE name webapi_user;登录名是否映射到数据库用户USE ERPDB; SELECT dp.name AS database_user, sl.name AS login_name FROM sys.database_principals dp JOIN sys.server_principals sl ON dp.sid sl.sid WHERE dp.name webapi_user;数据库用户是否属于有效角色SELECT dp.name, dpr.name AS role_name FROM sys.database_principals dp JOIN sys.database_role_members drm ON dp.principal_id drm.member_principal_id JOIN sys.database_principals dpr ON drm.role_principal_id dpr.principal_id WHERE dp.name webapi_user;显式权限是否被 DENY 覆盖SELECT pe.permission_name, pe.state_desc, o.name AS object_name FROM sys.database_permissions pe JOIN sys.database_principals dp ON pe.grantee_principal_id dp.principal_id LEFT JOIN sys.objects o ON pe.major_id o.object_id WHERE dp.name webapi_user AND pe.state_desc DENY;若发现DENY SELECT ON dbo.Users则GRANT SELECT无效必须先REVOKE DENY SELECT ON dbo.Users FROM webapi_user。我们曾为某医院系统修复过此类问题其report_user被DENY INSERT在所有表上但 DBA 以为GRANT SELECT就够了结果报表查询全失败。根源是DENY优先级高于GRANT必须显式REVOKE。5. 高级场景与避坑指南那些文档里不会写的实战经验5.1 Windows 认证在容器环境中的特殊处理Docker 容器运行 SQL Server 时Windows 认证无法直接使用但可通过Active Directory 容器化集成实现。核心思路是将容器加入 AD 域使其获得域身份。步骤如下在宿主机上安装realmd和sssd配置/etc/sssd/sssd.conf连接 AD。构建自定义 Docker 镜像基础镜像用mcr.microsoft.com/mssql/server:2019-CU25-ubuntu-20.04在 Dockerfile 中加入RUN apt-get update apt-get install -y realmd sssd sssd-tools adcli samba-common-bin \ echo [global]\nworkgroup CONTOSO\nsecurity ads\nrealm CONTOSO.COM /etc/samba/smb.conf启动容器时挂载 AD 配置docker run -d \ --name sql-server-ad \ -e ACCEPT_EULAY \ -e SA_PASSWORDYourStrongPass! \ -v /path/to/sssd.conf:/etc/sssd/sssd.conf \ -v /path/to/krb5.conf:/etc/krb5.conf \ -p 1433:1433 \ mcr.microsoft.com/mssql/server:2019-CU25-ubuntu-20.04进入容器执行realm join CONTOSO.COM -U adminCONTOSO.COM输入 AD 管理员密码。此时容器获得域身份CONTOSO\APP_Support组成员即可用 Windows 认证连接。但注意容器重启后需重新realm join因此必须在启动脚本中固化该步骤。5.2 SQL 认证的密码轮换自动化方案手动轮换 SQL 登录名密码是运维噩梦。我们为某电商集团设计了全自动轮换方案数据库层创建存储过程usp_RotateSQLPassword接受登录名和新密码参数执行ALTER LOGIN ... WITH PASSWORD。调度层用 SQL Server Agent 创建作业每周日凌晨 2 点执行该存储过程。密钥管理新密码通过 Azure Key Vault API 获取存储过程调用sp_execute_external_script调用 Python 脚本读取密钥。通知层轮换成功后自动邮件发送新密码给应用负责人并更新 Confluence 文档。关键代码片段-- 存储过程核心逻辑 CREATE PROCEDURE usp_RotateSQLPassword LoginName NVARCHAR(128), NewPassword NVARCHAR(128) AS BEGIN DECLARE SQL NVARCHAR(MAX) ALTER LOGIN QUOTENAME(LoginName) WITH PASSWORD NewPassword ;; EXEC sp_executesql SQL; -- 记录日志 INSERT INTO dbo.PasswordRotationLog (LoginName, RotationTime) VALUES (LoginName, GETDATE()); END避坑提示sp_executesql执行动态 SQL 时必须用QUOTENAME()防止 SQL 注入且NewPassword长度不能超过 128 字符否则报错Msg 15106。5.3 混合模式下的审计日志优化默认 SQL Server 审计日志default trace不区分认证类型导致审计报告无法判断是 Windows 还是 SQL 登录。必须启用SQL Server Audit并定制事件创建服务器审计CREATE SERVER AUDIT LoginAudit TO FILE (FILEPATH C:\SQLAudit\) WITH (ON_FAILURE CONTINUE); ALTER SERVER AUDIT LoginAudit STATE ON;创建服务器审核规范捕获登录事件CREATE SERVER AUDIT SPECIFICATION LoginSpec FOR SERVER AUDIT LoginAudit ADD (FAILED_LOGIN_GROUP), ADD (SUCCESSFUL_LOGIN_GROUP); ALTER SERVER AUDIT SPECIFICATION LoginSpec STATE ON;查询审计日志SELECT event_time, server_principal_name, client_hostname, client_ip, program_name, -- 关键字段authentication_type_desc 显示 WINDOWS 或 SQL authentication_type_desc FROM sys.fn_get_audit_file(C:\SQLAudit\*.sqlaudit, DEFAULT, DEFAULT) WHERE event_time DATEADD(HOUR, -24, GETDATE()) ORDER BY event_time DESC;这样审计报告就能清晰区分CONTOSO\johnWindows和webapi_userSQL满足等保三级“身份鉴别审计”要求。我在实际项目中发现很多团队启用审计后因日志文件过大导致磁盘爆满。解决方案是在CREATE SERVER AUDIT时添加MAXSIZE 100 MB和MAX_ROLLOVER_FILES 10并用 SQL Agent 作业每日压缩归档旧日志。这个细节90% 的教程都漏掉了。
返回列表