程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 從數據行入手保護SQL Server數據安全

從數據行入手保護SQL Server數據安全

編輯:關於SqlServer
主機網全新上線,買空間、服務器就上主機網,安全有保障!

在當今企業環境中,保證數據安全不是可有可無的工作。頻繁曝光的入侵和欺騙事件、薩班斯•奧克斯利法案、HIPAA法案規定和愛國者法案等都要求我們能夠做到,將正確數據提供給正確的用戶,防止其它無權限的人訪問。一般來說,“行級安全(row-level security)”的要求是:對數據庫中的數據以行為單位,設定只有特定用戶才可以訪問。可惜的是,SQL Server數據庫並不提供內置的行級別安全機制。

在本篇文章中,通過一個示例代碼(代碼清單1),來告訴大家一個在SQL Server中實現行級別安全的方法,以行為單位限定用戶的訪問權限,同時無需修改業務表的內容,不影響應用程序或表現層開發者,而且與用戶訪問數據的方式無關。該示例應用的模擬需求為:如何增加安全性到現有訂單數據庫中,限制經理只能訪問他們管理的部門或其子部門的數據,而不管用戶如何獲得該表,以及針對這個數據庫開發什麼樣的報表和查詢。

以下為引用的內容:

--create table script
CREATE TABLE dbo.UserAccess
(
UserID varchar(20) NOT NULL,
Department varchar(50) NOT NULL
)
CREATE TABLE [dbo].[Orders](
[OrderID] [int] NOT NULL,
[CustomerName] [varchar](20) NOT NULL,
[OrderTotal] [money] NOT NULL,
[Department] [varchar](50) NOT NULL
)
CREATE TABLE dbo.Departments
(
Department varchar(50) NOT NULL,
ParentDepartment varchar(50)
)
--end create table script

--script to clear then populate example tables

--clear tables
Delete from departments
Delete from orders
Delete from userAccess

--insert departments table
INSERT  INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('North America','')
INSERT INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('East','North America')
INSERT INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('Southeast','East')
INSERT INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('Northeast','East')
INSERT INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('West','North America')
INSERT INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('Southwest','West')
INSERT INTO [dbo].[Departments] ([Department],[ParentDepartment]) VALUES ('Northwest','West')

--insert orders table
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (1,'Harris','11.00','East')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (2,'Corrigan','22.00','Southeast')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (2,'Corrigan','22.00','Southeast')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (3,'Baldwin','33.00','Southeast')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (4,'Pillow','44.00','Northeast')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (5,'Carpenter','55.00','Northeast')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (6,'Meyer','66.00','West')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (7,'Gonzalez','77.00','Southwest')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (8,'Hall','88.00','Northwest')
INSERT INTO [dbo].[Orders] ([OrderID],[CustomerName],[OrderTotal],[Department]) VALUES (9,'Patrick','99.00','Southwest')

--insert user Access table
INSERT INTO [dbo].[UserAccess] ([UserID],[Department]) VALUES ('BLambert','Southwest')
INSERT INTO [dbo].[UserAccess] ([UserID],[Department]) VALUES ('MDavis','East')
INSERT INTO [dbo].[UserAccess] ([UserID],[Department]) VALUES ('MDavis','Southeast')
INSERT INTO [dbo].[UserAccess] ([UserID],[Department]) VALUES ('MDavis','Northeast')
INSERT INTO [dbo].[UserAccess] ([UserID],[Department]) VALUES ('WSimmons','Northeast')

--end script to clear then populate example tables

代碼清單1:提供了創建和加載示例表的腳本

主機網全新上線,買空間、服務器就上主機網,安全有保障!

行級別安全代碼范例

首先我們作出如下假設:

•使用SQL Server數據庫(微軟SQL Server 2000、2005或2008)

•所有表中都有一個共同的字段,使用它來決定誰可以看什麼數據(本例中就是department字段)

•通過不同的用戶id來加強應用程序調用數據庫的安全性,而不是通過一個單一的admin用戶id。

舉例來說,圖1所示數據結構包含:Orders表,包含一個客戶名稱、訂單收入和銷售部門;一個部門查閱表(Departments),包含父部門字段;一個用戶訪問表(UserAccess),在用戶和他有權限查看的部門之間建立聯系。用戶訪問表的每一行數據代表一個正確的用戶/部門組合。如果一個用戶有權限訪問的部門下設許多子部門,那麼這個父部門和每一個子部門在表中各占據一行數據。

 

 

圖1 該數據庫模型圖顯示了本例中所用到的表

讓訂單數據保持安全的關鍵是,通過SQL Server的表值型函數來保護它,該函數要求使用當前用戶的id作為參數。表值型函數與其它函數一樣可以接受參數,但是返回結果為一個表,而並非一個變量。在這個函數內,通過其安全屬性聯合要保護的表與用戶訪問表,將表的結果限定在與指定用戶id相關的范圍之內。

示例1定義了一個表值型函數,根據UserAccess表中的限制用戶可以查看的內容,返回訂單數量和訂單的總收入。

以下為引用的內容:

CREATE FUNCTION [dbo].[GetOrderSummary]
(
@User_Id VARCHAR(20)
)
RETURNS TABLE
AS
RETURN
(
SELECT  count(*)   as OrderCount,
   sum(OrderTotal) as Receipts
  FROM  dbo.Orders  o
  Join  dbo.UserAccess ua
  On  o.Department = ua.Department
  WHERE ua.UserID = @User_Id
)

示例1:創建保護訂單數據的表值型函數的SQL語句

而圖2顯示了該函數的執行示例,以及相關表的數據內容,如表1、表2和表3.

 

 

圖2 表值型函數執行示例

 

 

表1 UserAccess示例表內容

 

 

表2 Orders示例表內容

 

 

表3 Department表內容

主機網全新上線,買空間、服務器就上主機網,安全有保障!

顯示受保護表內容

通過表值型函數保護了某個表之後,你然後可以通過類似示例2的視圖將其展示給用戶。該視圖調用了上面定義的表值型函數,並使用參數“user”,在SQL Server中這是一個內置函數,返回當前活躍用戶的ID。

以下為引用的內容:

CREATE VIEW  [dbo].[OrderSummary]
AS
SELECT  OrderCount,
Receipts
FROM          dbo.GetOrderSummary(USER)

示例2:創建一個視圖讓安全用戶訪問受保護表的SQL

這個視圖是用戶被授予訪問權限的唯一對象,即使用戶不具有權限使用前面的表值型函數或訪問受保護表,他也可以獲得被許可查看的數據。

實際應用思考

在應用程序開發實際情況中,這種方式往往需要一個以上的屬性來定義用戶行級別權限,而且往往需要對多個表應用安全機制。

另外,不同的數據可能具有不同的安全考慮。舉例來說,一個用戶可能有權限訪問某個區域的銷售結果,但不能訪問匯總薪酬數據。在復雜的實際環境中成功運用這個戰略的關鍵是,收集並確認來自業務的需求,然後根據這些需求來選擇合適的屬性來實施行級別安全。

使用活動目錄的企業,可以按照活動目錄組來使用這種方式獲得安全性,而並一定僅限於使用用戶ID,實現方法非常簡單,只需要在UserAccess表中使用活動目錄組替代用戶ID即可。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved