權限問題是 SQL Server 開發運維中最常見的阻礙。本文針對兩大經典錯誤:「SELECT 權限被拒絕」 與 「SA 登入失敗:不與信任 SQL Server 連線相關聯」,提供根因分析、解決步驟與預防原則。
拒絕了對對象 'data' (資料庫 'xxx', 所有者 'dbo') 的 SELECT 權限
db_denydatareader 固定資料庫角色。db_datareader 或物件層級 GRANT SELECT,DENY 仍會生效封鎖存取。db_denydatareader 當成「資料讀取者」而勾選。db_denydatareader。
USE [YourDatabase];
GO
ALTER ROLE db_denydatareader DROP MEMBER [YourUser];
-- 或舊版相容
EXEC sp_droprolemember 'db_denydatareader', 'YourUser';
GO
DENY (資料庫/結構描述/物件層級)GRANT (物件層級)GRANT (結構描述層級)GRANT (資料庫層級,如 db_datareader)PUBLIC 隱性權限最佳實務:避免使用
db_denydatareader/db_denydatawriter。採用「最小權限原則」:僅GRANT必需物件權限,不授予多餘角色。
用戶 'sa' 登錄失敗。該用戶與可信 SQL Server 連接無關聯。
sa) 皆無法連線。SQL Server (MSSQLSERVER) → 重新啟動。
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
N'Software\Microsoft\MSSQLServer\MSSQLServer',
N'LoginMode', REG_DWORD, 2; -- 2 = 混合模式
-- 之後仍需重啟服務
若混合模式已啟用但仍失敗,檢查 sa 是否啟用:
| 面向 | 建議 |
|---|---|
| 安裝標準化 | 安裝腳本/組態管理 (DSC/Ansible) 強制設定混合模式、強制 sa 強密碼、停用 sa 或改名。 |
| 權限模型 | 建立應用程式專用登入/使用者,授予結構描述級 GRANT,拒絕直接使用 sa/系統管理員帳號連線應用。 |
| 定期稽核 | 查詢 sys.database_role_members 找出異常 db_denydatareader 成員;查詢 sys.server_principals 檢查 SQL 登入狀態。 |
| 錯誤訊息國際化 | 錯誤訊息可能為中文/英文/其他語言,依 @@LANGUAGE 而定,排查時以錯誤號 (18452, 229) 為準。 |
權限問題本質上是「最小權限原則」執行不到位。db_denydatareader 是反模式陷阱;混合模式未啟用是安裝預設值陷阱。建立標準化安裝檢查清單、權限矩陣文件、定期權限稽核腳本,能從根源消除此類事故。