本文大綱:
說明
Microsoft Azure SQL Database V12 推出資料列層級安全性(Row-Level Security,RLS),為儲存在 SQL Database 裡的資料提供有別於以往的保護機制,要使用這項功能應用程式幾乎不需要過多的修改就可以相容於資料列層級安全性,直接享受資料列層級安全性所帶來的細緻存取控制特性,並且讓資料安全性邏輯集中於資料庫層級,管控資料的安全性可以交給資料庫來完成,應用程式只要像過去那樣連接資料庫並存取資料,藉由資料列層級安全性功能就可以達到資料隔絕的效果,有效避免應用程式開發時,可能因為疏忽而導致存取不該存取的資料。
截至本文撰寫為止,北歐和西歐地區的資料中心 Azure SQL Database V12 已經進入 GA 階段,其他地區除了東亞、東南亞及日本地區資料中心尚未公布 GA 時程外,將依照預定時程陸續於 2015 年 2 月初脫離預覽階段[1]。
權限
要使用資料列層級安全性功能,所需具備的權限如下:
ALTER ANY SECURITY POLICY 的權限。
ALTER 結構描述的權限。
篩選述詞函式 SELECT 和 REFERENCE 的權限。
目的資料表和資料行的 REFERENCE 的權限。
限制
目前資料列層級安全性仍有下列的功能限制:
資料列層級安全性不相容於記憶體最佳化 OLTP(In-Memory OLTP)資料表。
資料列層級安全性不相容於異動資料擷取(Change Data Capture)。
全文檢索索引(Full-Text indices)和 DBCC SHOW_STATISTICS 可能透露未經 Security Policy 過濾的資訊。
學習目標
建立 SQL Database。
設定防火牆規則。
實作資料列層級安全性。
修改資料列層級安全性原則。
建立 SQL Database
假設您尚未建立任何 SQL Database 伺服器,請登入 Microsoft Azure 管理入口網站或預覽版管理入口網站(本文以預覽版管理入口網站來做示範),在頁面左下角點選新增,接著點選 SQL Database。
名稱的部分輸入您所要建立的 SQL Database 名字,然後點選伺服器以選擇 SQL Database 要建立在哪一台伺服器,由於目前尚未存在任何伺服器,因此點選建立新的伺服器。
建立伺服器時,您可以指定伺服器的名稱(現有的管理入口網站無法指定伺服器名稱,只有預覽版的管理入口網站才可以)以及伺服器管理員的帳號密碼,並且選擇伺服器要建立在哪一資料中心,在此我們選擇已經 GA 的北歐資料中心。
在已經 GA 的地區建立 SQL Database 時,CREATE V12 SERVER(LAST UPDATE)選項預設為 YES,表示在建立伺服器的同時會將伺服器升級為 SQL Database V12 的版本,您才有辦法使用這個版本所推出的新功能,如本文要介紹的資料列層及安全性。
與現有的 Azure 管理入口網站不同的是,預覽版管理入口網站可以讓您選擇 SQL Database 的範本,當然您可以選擇空白資料庫範本,那就跟過去建立 SQL Database 一樣,一開始資料庫是空的;您也可以選擇範例資料庫,讓管理入口網站幫您產生一個含有測試資料的 SQL Database;甚至是透過備份在儲存體的備份檔來建立 SQL Database。
再來是依照您所需要的服務層級及效能水準來選擇適當的價格區間,預設是 Standard S0 的價格區間,您可以點選瀏覽所有定價層來選擇更多種類的價格區間,而 SQL Database 正是根據您所選擇的價格區間來收費。
定序的部分預設為 SQL_Latin1_General_CP1_CI_AS,您可以自行輸入 SQL Database 所要使用的定序名稱,管理入口網站會自動檢查定序名稱輸入是否正確。順帶一提,若您選擇使用範例資料庫來建立 SQL Database,那麼您將無法自行指定定序名稱,因為範例資料庫會直接決定所要使用的定序。
預覽版管理入口網站可以為各項您所建立的服務指定資源群組,將來可以將相同應用程式所要使用的各項資源放在同一個資源群組以方便管理,同時資源群組亦可以當作該群組內各項資源的生命週期界限。
您可以選擇將 SQL Database 建立在新的資源群組,此時只要輸入資源群組的名稱即可,或是點選使用現有的資源群組並選擇要將 SQL Database 建立在哪個資源群組之中。
最後則是選擇訂用帳戶名稱就可以按下建立來開始建立 SQL Database。
設定防火牆規則
為了保護 SQL Database 的安全,預設僅允許 Microsoft Azure 服務存取 SQL Database,若您想要在 Microsoft Azure 以外來存取 SQL Database,必須將要遠端管理用的電腦 IP 位址加入防火牆規則。
請點選前一節所建立的 SQL Database 伺服器,接著點選設定。
於設定頁面點選防火牆,輸入防火牆規則名稱、起始 IP 和結尾 IP,然後按儲存。
若順利新增防火牆規則,您將會看到如下圖的訊息。
若您想要確認目前的 SQL Databae 伺服器是否為最新版本,可以在設定頁面中點選最新版更新來查看。
防火牆規則加入之後,就可以在 SQL Database 頁面中點選屬性來查看伺服器名稱,這個名稱是您使用 SSMS (SQL Server Management Studio)遠端管理時會用到。
目前預覽版管理入口網站並未提供網頁版的 SQL Database 管理工具,所以您必須使用 SSMS 來連接 SQL Database。但在您開始使用 SSMS 連接 SQL Database V12 前,必須下載並安裝 SQL Server 2014 CU5,有關 SQL Server 2014 Management Studio 更新 CU5 之後增加那些針對 SQL Database V12 的新功能,詳見參考資料 6。
實作資料列層級安全性
我們在前面所建立的 SQL Database 中的 Customer 資料表增加一個資料行 UserID,並且透過下列 T-SQL 來更新 UserID 資料行。
UPDATE [SalesLT].[Customer] SET UserID = 'u1' WHERE CustomerId % 2 = 0
GO
UPDATE [SalesLT].[Customer] SET UserID = 'u2' WHERE CustomerId % 2 = 1
GO |
經由上述 T-SQL 指令碼,我們將資料分成兩部分,其中 CustomerId 可以被 2 整除的資料只有使用者 u1 可以查詢,剩下的部分則只有使用者 u2 可以查詢;而使用者 m 則是可以查詢 Cusomter 資料表的所有資料。
為了模擬上圖的情境,我們使用下列 T-SQL 指令碼來建立資料庫使用者,並且授予 SELECT 資料表 [SalesLT].[Customer] 的權限。
--建立沒有和登入關聯的資料庫使用者 CREATE USER m WITHOUT LOGIN
GO
CREATE USER u1 WITHOUT LOGIN GO CREATE USER u2 WITHOUT LOGIN GO --授予SELECT資料表[SalesLT].[Customer]的權限 GRANT SELECT ON [SalesLT].[Customer] TO m GO GRANT SELECT ON [SalesLT].[Customer] TO u1 GO GRANT SELECT ON [SalesLT].[Customer] TO u2 GO |
建立篩選述詞函式(Filter Predicate Function)
建議建立一個單獨的結構描述來給資料列層級安全性相關物件所使用,以達到和其他資料庫物件隔離的目的。
此外,我們尚需一個讓 SQL Database 判斷如何限制哪個使用者可以存取哪些資料的篩選述詞函式,該函式必須符合下列條件:
必須是嵌入資料表值函式(inline table valued function)函式,否則在建立資料列層級安全性原則時會發生下圖的錯誤。
WITH SCHEMABINDING 為必要之參數,若將未指定 WITH SCHEMABINDING 的函式指派給資料列層級安全性原則,會發生如下圖的錯誤。
下列 T-SQ L指令碼將會建立嵌入資料表值函式函式,當 USER_NAME() 回傳值等於 @UserID 變數內容,以及 USER_NAME() 回傳值等於使用者 m 時,會回傳 1,以確認使用者可以查詢的資料範圍,其實回傳值的內容並不重要,主要是判斷結果級是否為空的來決定篩選結果。
--建立結構描述 CREATE SCHEMA Security;
GO
--建立篩選述詞函式 CREATE FUNCTION Security.fn_securitypredicate(@UserID AS sysname) RETURNS TABLE WITH SCHEMABINDING AS RETURN SELECT 1 AS fn_securitypredicate_result WHERE @UserID = USER_NAME() OR USER_NAME() = 'm'; |
建立安全性原則(Security Policy)
SQL Database 主要是藉由資料列層級安全性原則來依照篩選述詞函式的條件回傳資料,因此下列 T-SQL 指令碼主要是用來建立這個原則並引用前面所建立的篩選述詞函式來讓資料庫引擎幫您篩選資料,這也是為什麼應用程式可以不需自行判斷要查詢哪些條件,就可以只取得符合安全性原則的資料。
其中 ADD FILTER PREDICATE 參數用來告訴安全性原則要使用哪個函式來篩選資料;ON 參數則是指定安全性原則所要套用的資料表;而 STATE 參數設為 ON,是用來在建立安全性原則後將之啟用。
--建立安全性原則 CREATE SECURITY POLICY Security.spo_GetCustomerByUserID ADD FILTER PREDICATE Security.fn_securitypredicate(UserID) ON [SalesLT].[Customer] WITH (STATE = ON); |
測試資料列安全性原則
為了測試套用資料列層級安全性的效果,可以使用 EXECUTE AS USER 安全性陳述式來快速切換工作階段的執行內容。
以下 T-SQL 指令碼分別以使用者 u1、u2 以及 m 的執行內容來查詢 [SalesLT].[Customer] 資料表。
EXECUTE AS USER = 'u1'
SELECT UserID,COUNT(UserID) FROM [SalesLT].[Customer] GROUP BY UserID
REVERT
GO
EXECUTE AS USER = 'u2'
SELECT UserID,COUNT(UserID) FROM [SalesLT].[Customer] GROUP BY UserID
REVERT
GO
EXECUTE AS USER = 'm'
SELECT UserID,COUNT(UserID) FROM [SalesLT].[Customer] GROUP BY UserID
REVERT |
由下圖可見,即使未針對資料表使用任何 WHERE 條件,SQL Database 會依照安全性原則回傳符合篩選述詞的資料列,而不會回傳所有資料表的內容,如此一來就可以集中由資料庫層級來管理資料的安全性,應用程式只要直接查詢即可,是不是相當方便呢?
修改資料列層級安全性原則
當然安全性原則可以套用多個篩選述詞函式,可以用 ALTER SECURITY POLICY 陳述式來加入、刪除篩選述詞函數,甚至是停用安全性原則。
--移除篩選述詞函式 ALTER SECURITY POLICY Security.spo_GetCustomerByUserID DROP FILTER PREDICATE ON [SalesLT].[Customer]
--加入篩選述詞函式 ALTER SECURITY POLICY Security.spo_GetCustomerByUserID ADD FILTER PREDICATE Security.fn_securitypredicate(UserID) ON [SalesLT].[Customer]
--停用安全性原則 ALTER SECURITY POLICY Security.spo_GetCustomerByUserID WITH(STATE=OFF)
--啟用安全性原則 ALTER SECURITY POLICY Security.spo_GetCustomerByUserID WITH(STATE=ON)
|
參考資料
進階學習
如欲瞭解更多資安議題,建議您觀看以下免費課程:MVP Jason Huang 於微軟實戰課程日主講的「雲端安全實作建議」,希望對您的學習有幫助。