經常有人來問我特定 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]

結語

資料庫中還有許多其他物件都有可能因為參考到資料庫使用者而無法刪除,但熟悉了基本觀念後,應該就會懂得融會貫通,相信日後遇到無法刪除使用者的問題應該也能輕鬆的自行解決。

来源:http://blog.miniasp.com/post/2011/08/20/SQL-Server-Security-and-Unable-to-delete-database-user-problem.aspx

[转]SQL Server 安全性概論與無法刪除資料庫使用者的解決辦法的更多相关文章

  1. C# [Win32] [API] WS_TABSTOP 無效的解決辦法

    關鍵: IsDialogMessage function MSG msg; int bRet = 1; while (bRet != 0) { if (PeekMessageW(&msg, ( ...

  2. 如何將 MySQL 資料庫轉移到 Microsoft SQL Server 與 Azure SQL Database

    MySQL 是相當常用之資料庫伺服器,而微軟雲端服務 Microsoft Azure 上 Azure SQL Database 是一個功能強大且經濟實惠的選擇,透過本篇文章,使用 SQL Server ...

  3. SQL Server安全性专题一:简介

    原文:SQL Server安全性专题一:简介 一. 安全威胁与法则 1. 安全定义 2. 安全威胁 3. 安全法则 安全定义: 在SQLServer环境中,安全性可以认为是[数据保护].包括:  数 ...

  4. 第十三周翻译:SQL Server安全级别1:SQL Server安全性概述

    SQL Server安全级别1:SQL Server安全性概述 源自:Stairway to SQL Server Security Level 1: Overview of SQL Server S ...

  5. SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)

    SQL Server 表的管理_关于数据增删查改的操作的详解(案例代码)-DML 1.SQL INSERT INTO 语句(在表中插入) INSERT INTO 语句用于向表中插入新记录. SQL I ...

  6. SQL SERVER 安全性体系

    主体和安全实体 在 SQL Server 2008中,“主体”就是可以访问受保护资源且能获得访问资源所需权限的任何个人.组或流程.与旧版 SQL Server 一样,可以在 Windows 中定义主体 ...

  7. 如何查詢 SQL Server 資料庫中欄位值為 NULL 的資料(转)

    最近使用mssql的时候对于未null的字段查询不到 http://blogs.msdn.com/b/jchiou/archive/2008/05/01/sql-server-null.aspx 先建 ...

  8. 在 SQL Server 2012 附加 Adventure Works 範例資料庫

    原文地址:http://technet.microsoft.com/zh-tw/library/eb1f9417-4cca-4575-a725-187bcd60c7e7 附加数据库时报错 错误5123 ...

  9. [ Database ] [ Sybase ] [ SQLServer ] sybase 與SQL Server的界接方式

    目前我們有個專案Server A安裝了 SQL Server 2012,有個需求需要連線到另外一台Server B上的 Sybase 12.5的view, 先前試過了很多方法都無法連通.主要的原因是因 ...

随机推荐

  1. java 类与对象基础整理

    之前学习javaSE的时候,没有针对性地对对类与对象的一些基础进行整理,下面这些内容是笔记内容整理后的,希望以后自己可以通过这些博客时常复习! 一.类and对象的基础 类似于类的生命啊,类与对象的关系 ...

  2. class文件反编译工具jd-gui下载地址

    https://github.com/java-decompiler/jd-gui/releases windows下载: 下载后打开软件,直接将jar包拖进去: 效果图非常美观:

  3. Linux pip 安装模块时,一直黄字错误:Could not find a version that satisfies the requirement

    参考原文:https://blog.csdn.net/u012592062/article/details/51966649 这时我们用国内的镜像源来加速 pip install 包名-i http: ...

  4. wamp配置步骤

    对于初做PHP网站的朋友来说,第一步肯定是希望在自己电脑是搭建PHP环境,省去空间和上传的麻烦!但搭建环境也不是件容易的事情,特别是对于新手同学来说!因此在这里跟大家介绍我作为一名新手在使用的方便好用 ...

  5. 给div加上padding和border,如何不让div整体改变

    最近要入门H5,遇到很多困惑,所以,每解决一个,我就要写在博客里,以防忘记! 给div加上padding和border,如何不让div整体改变? 如果想要实现这样的效果,只需要在这个div块中写入 b ...

  6. java IO流实现删除文件夹以及文件夹中的内容

    这篇主要是对IO文件流对文件常用处理中的删除文件夹,平时我们直接删除文件夹既可以删除里面的全部内容. 但是java在实现删除时,只能是文件才会被删除. 所以这里需要定义一个方法,来递归调用方法(递归调 ...

  7. js基本数据类型和引用类型的区别详解-笔记

    原文参考http://mp.weixin.qq.com/s/apFyUgqT5N-bsDUjP4Eryg 笔记总结 首先记住js中的基础数据类型undefined,null,boolean,strin ...

  8. CentOS 7运维管理笔记(5)----源代码安装Apache 2.4,搭建LAMP服务器

    ##########################    2016-07-07-Thu--20:34 补充 ##################### 编译安装OpenSSL笔记: 如果系统要使用 ...

  9. android启动应用

    private void openApp(String packageName) { PackageInfo pi = getPackageManager().getPackageInfo(packa ...

  10. OTRS工单管理系统

    OTRS简介 OTRS的名字是由Open-source Ticket Request System首字母縮略字而来,是一个开源的缺陷跟踪管理系统软件.  OTRS将电话,邮件等各种渠道提交进来的服务请 ...