[转]SQL Server 安全性概論與無法刪除資料庫使用者的解決辦法
經常有人來問我特定 SQL Server 資料庫裡的使用者無法刪除的問題,這問題其實跟 SQL Server 的安全性架構有很大關係,解決這個問題當然還是瞭解觀念的重要性大於知道如何解決問題。除了講解觀念外,本篇文章也會列出一些出問題時的情境,方便快速解決問題。
我先假設各位已經知道 驗證 (Authentication) 與 授權 (Authorization) 的差別,簡單的來說 驗證負責辨識登入者的身份,而授權在於提供特定特定身份授與特定的操作權限。
在 SQL Server 裡提供了兩種驗證模式,分別是 Windows 驗證 (Windows Authentication) 與 混合模式驗證 (Mixed Modes authentication),藉以控制應用程式連接 SQL Server 的方式。另外,SQL Server 又區分了兩種登入的類型,分別是 Windows 登入 與 SQL Server 登入,在從應用程式連接資料庫時,使用 Windows 登入可以不用輸入密碼在連線參數上,這種登入方式是比較建議的登入方法。
在設定登入帳號時,該帳號可以隸屬於一個以上的 伺服器角色 (Server Role),這些在 SQL Server 中存在的伺服器角色數量是固定的,無法新增、也無法刪除,預設所有新增的「登入帳號」都會自動歸類在 public 這個伺服器角色下,這個 public 角色只有允許連接 SQL Server 的權力而已,並沒有任何資料庫的的存取權限。
所以我們從 SSMS ( Management Studio ) 中所看到的「安全性」節點,其實是為於「伺服器節點」之下,並不隸屬於任何資料庫,這是應用程式連接 SQL Server 時的第一個安全性關卡,應該妥為設定才行,不應該給予登入帳號有過大的權限,例如將該登入帳號加入到 sysadmin 伺服器角色之類的。
因此,這裡所儲存的是 登入帳號 (Login),而非 資料庫使用者 (Database User),這點非常重要。
當我們在任意一個資料庫中建立資料庫使用者時,所建立的其實是一個所謂的 安全性主體 (security principal),他代表的是一個能夠被賦予安全性設定的對象,也就是一個可授權的對象。
這裡的 資料庫使用者 在建立時必須對應到一個 登入帳戶,而在建立時可以設定任意的使用者名稱,方便好記即可(一般我們會習慣設定使用者名稱與登入名稱一致),並且挑選出一個登入帳戶,在設定好之後我們就可以針對這個 資料庫使用者 設定各種權限相關的設定,例如:資料庫角色、安全性實體、…等等。
如下圖是透過 SSMS 新增 資料庫使用者 的畫面,我看過許多人在建立資料庫使用者時,會勾選如下圖藍色框框的勾選項目,也就是設定該使用者「擁有特定的結構描述」,勾選這一項就會導致日後無法刪除資料庫使用者的問題,解決辦法在本文稍後會提及。
除了設定 SQL Server 預設的 資料庫角色 外,你也可以自行新增資料庫角色,並設定該角色應該有哪些權限能用,基於資安的最小權限原則 (Principle of least privilege),我們應該授與資料庫使用者最小的使用權限,以加強資料庫的存取安全性,這時我們就可以透過自訂的資料庫角色來設定適當的權限,最後再將資料庫使用者加入到該資料庫角色即可將權限套用完成。
若要設定 資料庫使用者 或 資料庫角色 的細部權限,我們可以切換至 安全性實體 (Securables) 頁籤。所謂的 安全性實體 (Securable) 與 安全性主體 (Security Principle) 不太一樣,但中文卻被翻譯的非常相似,讀者必須特別小心。這裡的 安全性實體 (Securables) 指的是可以指派權限給特定 資料庫使用者 或 資料庫角色 的資料庫物件。
在你搜尋出 安全性實體 (或 資料庫物件) 後,就可以針對這些物件設定更細部的權限,如下圖示,我選擇了一個預存程序,下方的權限部分就又分為 改變、取得擁有權、執行、控制、檢視定義 等權限,如果你只需給特定使用者「執行」的權限,就只要在「執行」權限的「授與」這一欄勾選即可。
接下來,在資料庫層級的安全性中,還有一個所謂的 結構描述 (Schema) 的觀念,這是從 SQL Server 2005 開始才有的概念,在 SQL Server 2000 以前,使用者名稱本身就是資料庫物件的一部分,但新的版本不再有這種限制,而改用 結構描述 (Schema) 來「擁有」這些資料庫物件。
如果由 結構描述 (Schema) 來「擁有」這些資料庫物件,那麼應該由誰來「擁有」結構描述 呢?當然是透過 資料庫使用者 或 資料庫角色 囉!
第 1 種無法刪除的情境:資料庫預設 結構描述 (Schema) 的擁有者被指定了想刪除的資料庫使用者
也就是說,當有特定 結構描述 被特定 資料庫使用者 所擁有時,該 資料庫使用者 就會因為被鎖定導致無法刪除,所以在刪除資料庫使用者經常會遇到一個很常見的錯誤訊息如下:
Msg 15138, Level 16, State 1, Line 2
資料庫主體在資料庫中擁有 結構描述 且無法卸除。
那麼我們要怎樣才能一次瀏覽所有 結構描述 (Schema) 的擁有者是誰呢?以下這行 T-SQL 可以幫你列出
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
如果你發現你想刪除的資料庫使用者擁有了特定 結構描述 (Schema) 的話,你可以修改特定 結構描述 的擁有者給其他人,例如:dbo
移轉擁有權的 T-SQL 語法如下:
ALTER AUTHORIZATION ON SCHEMA::[db_owner] TO [dbo]
第 2 種無法刪除的情境:無法刪除多餘的 結構描述,所以也連帶無法刪除資料庫使用者
這問題並不常見,除非開發人員真的亂新增結構描述才會這樣,否則結構描述應該是在資料庫設計階段所設計過的,況且我們只要把該結構描述的擁有者改成其他資料庫使用者或資料庫角色,就可以刪除該資料庫使用者了。
但如果因為設計有所改變而需要刪除特定結構描述卻無法刪除的話,其錯誤訊息如下:
訊息 3729,層級 16,狀態 1,行 2
無法 drop schema TESTUser,因為物件 'PK_Table_1' 正在參考它。
為了要刪除該結構描述,你必須要先轉移這些被參考到的資料庫物件的結構描述到另一個結構描述裡,以下是搜尋出所有該結構描述所用到的物件清單,這一行 T-SQL 指令可以幫你快速找出使用該結構描述的物件:(備註:如下範例請將 MySchema 修改成你的結構描述名稱)
SELECT schema_name(uid) as SCHEMA_NAME, * FROM sysobjects
WHERE schema_name(uid) = 'MySchema'
假設我們要將 MySchema.View_1 物件轉移到 dbo 結構描述,其物件名稱會變成 dbo.View_1,那麼我們可以使用以下 T-SQL 執行轉移動作:
ALTER SCHEMA dbo TRANSFER MySchema.View_1
第 3 種無法刪除的情境:有資料庫角色的擁有者被指定了想刪除的資料庫使用者
這種問題的錯誤訊息如下:
Msg 15421, Level 16, State 1, Line 2
資料庫主體擁有資料庫角色且無法卸除。
一樣只要轉移擁有者即可,以下是方便查出所有資料庫角色擁有者的 T-SQL 語法:
SELECT user_name(owning_principal_id) as OWNER_NAME, * FROM [sys].[database_principals]
以下是轉移資料庫角色擁有者的語法:
ALTER AUTHORIZATION ON ROLE::[testrole] TO [dbo]
第 4 種無法刪除的情境:有 服務 的擁有者被指定了想刪除的資料庫使用者
這種問題的錯誤訊息如下:
Msg 15138, Level 16, State 1, Line 2
資料庫主體在資料庫中擁有 服務 且無法卸除。
以下是方便查出所有服務擁有者的 T-SQL 語法:
SELECT user_name(principal_id) as OWNER_NAME, * FROM [sys].[services]
結語
資料庫中還有許多其他物件都有可能因為參考到資料庫使用者而無法刪除,但熟悉了基本觀念後,應該就會懂得融會貫通,相信日後遇到無法刪除使用者的問題應該也能輕鬆的自行解決。
[转]SQL Server 安全性概論與無法刪除資料庫使用者的解決辦法的更多相关文章
- C# [Win32] [API] WS_TABSTOP 無效的解決辦法
關鍵: IsDialogMessage function MSG msg; int bRet = 1; while (bRet != 0) { if (PeekMessageW(&msg, ( ...
- 如何將 MySQL 資料庫轉移到 Microsoft SQL Server 與 Azure SQL Database
MySQL 是相當常用之資料庫伺服器,而微軟雲端服務 Microsoft Azure 上 Azure SQL Database 是一個功能強大且經濟實惠的選擇,透過本篇文章,使用 SQL Server ...
- SQL Server安全性专题一:简介
原文:SQL Server安全性专题一:简介 一. 安全威胁与法则 1. 安全定义 2. 安全威胁 3. 安全法则 安全定义: 在SQLServer环境中,安全性可以认为是[数据保护].包括: 数 ...
- 第十三周翻译:SQL Server安全级别1:SQL Server安全性概述
SQL Server安全级别1:SQL Server安全性概述 源自:Stairway to SQL Server Security Level 1: Overview of SQL Server S ...
- SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)
SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)-DML 1.SQL INSERT INTO 语句(在表中插入) INSERT INTO 语句用于向表中插入新记录. SQL I ...
- SQL SERVER 安全性体系
主体和安全实体 在 SQL Server 2008中,“主体”就是可以访问受保护资源且能获得访问资源所需权限的任何个人.组或流程.与旧版 SQL Server 一样,可以在 Windows 中定义主体 ...
- 如何查詢 SQL Server 資料庫中欄位值為 NULL 的資料(转)
最近使用mssql的时候对于未null的字段查询不到 http://blogs.msdn.com/b/jchiou/archive/2008/05/01/sql-server-null.aspx 先建 ...
- 在 SQL Server 2012 附加 Adventure Works 範例資料庫
原文地址:http://technet.microsoft.com/zh-tw/library/eb1f9417-4cca-4575-a725-187bcd60c7e7 附加数据库时报错 错误5123 ...
- [ Database ] [ Sybase ] [ SQLServer ] sybase 與SQL Server的界接方式
目前我們有個專案Server A安裝了 SQL Server 2012,有個需求需要連線到另外一台Server B上的 Sybase 12.5的view, 先前試過了很多方法都無法連通.主要的原因是因 ...
随机推荐
- jsp servlet基础复习 Part2--GET,Post请求
最近进行servlet和jsp方面的梳理复习时,发现以前忽略了一个非常重要的知识点:get和post的请求(如果你觉得两者仅仅是提交数据量的大小以及方式不同就大错特错了)的正真区别,下面进行简答的整理 ...
- Nginx 502错误总结
http请求流程:一般情况下,提交动态请求的时候,nginx会直接把 请求转交给php-fpm,而php-fpm再分配php-cgi进程来处理相关的请求,之后再依次返回,最后由nginx把结果反馈给客 ...
- linux设置静态获取ip
vsphere client 创建虚拟机后,默认是动态获取ip ,如果想要改为静态ip: 修改网卡eth0 (不一定每个人都是eth0,比如有的是ens160) vim /etc/sysconfig/ ...
- Jvm运行时内存解析
一.jvm的概念 在了解jvm的概念之前,我们先来了解java平台的逻辑结构,图片来自<深入java虚拟机> 从图中我们可以看到jdk包含了jre,java语言和java开发工具和Api, ...
- CSS3自定义loading效果
效果: 使用CSS3完成loading的制作 css样式: <style type="text/css"> .mask { position: fixed; left: ...
- 盒模型的属性丶display显示丶浮动
一丶盒模型的属性(重要) 1.padding padding是标准文档流,父子之间调整位置 <!DOCTYPE html> <html> <head> <me ...
- Canvas中的save方法和restore方法
初学者也许会误认为canvas中save方法是用来保存绘图状态的图形,而restore方法是用来还原之前保存的绘图状态的图形,其实不然. save():保存当前的绘图状态. restore():恢复之 ...
- cnpm 安装
国内npm 安装比较慢,可选择cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org
- chrome调试工具DevTools的使用 以及 localhost在移动端不能访问的问题
1.手机和pc 都需要装 chrome浏览器 2.手机端打开开发者模式和usb调试 (华为nova的手机小坑,需要选择usb 配置为可传输文件的状态) 3.经过以上操作打开chrome://inspe ...
- IIFE
一.IIFE IIFE:immediately-invoked function expression,即时调用函数表达式. 如果一个函数,在定义的时候,就想直接调用它,就是一个IIFE. 函数执行方 ...