第六章
細粒度數據操作權限
很多系統對于黑客不堪一擊。請看這樣的示例:
1.
前臺展現客戶能查看的客戶數據,而且用戶能刪除的客戶數據,就是前臺展現出來的數據;
2.
當用戶選擇某個用戶,點擊刪除按鈕,后臺執行刪除操作。
比如,請求后臺刪除的url是:http://www.test.com/crm/customer.do?id=3
假設,id=13的客戶在前臺不顯示(因為當前用戶沒有對該客戶數據有刪除權限),但用戶輸入http://www.test.com/crm/customer.do?id=13
顯然id=13的客戶將被刪除掉。
有開發者建議采用id值不要使用自增長型,而改用其他型,比如hashcode等。這也不大合適,可以使用爬蟲輕松地將漏洞爬出來。
顯然,僅僅通過界面層次控制數據級權限是不夠的。
解決方案
數據級防火墻
顯然,需要為業務系統構建一道數據級防火墻。該防火墻能夠判斷當前用戶對請求的數據,是否有操作權限。如果沒有操作權限,告知業務系統,且告知拒絕理由。
防火墻位置
后臺業務方法被執行前,需要做個權限檢查。檢查通過后,才執行該操作,否則不予執行。
這種注入模式有2種,1,硬編碼注入;2,AOP方法攔截。
硬編碼注入,類似這樣:
…
if( SecurityService.permit( user, customer, Privilege.DELETE_CUSTOMER ) ) {
customerService.delete( customer );
} else {
…
// 對該客戶沒有刪除權限,轉移到提示界面
}
…
AOP方法攔截,通過給業務方法annotation簽名。當該方法被執行時,自動觸發權限判斷邏輯。
public interface CustomerService {
/**
* @security id=DELETE_CUSTOMER
public void delete( Customer customer, User user );
}
權限邏輯
大多業務系統,采用if
else邏輯判斷,判定用戶是否具有對某數據的操作權限。
這種細粒度的權限邏輯,無法或者說非常難使用某種模型來自動處理。因此大多系統采取硬編碼模式實現權限邏輯。
本章介紹怎樣使用Metadmin來管理權限邏輯。
如果使用Metadmin
以下演示來自metadmin下載包里面包含的演示示例,可以在www.metadmin.com 下載Metadmin安裝程序包。
Metadmin不通過編程,而是通過設計器快速設計出權限邏輯,并可在線測試權限邏輯。
怎樣與系統集成
MetadminService類,提供如下方法:
static Decision
|
permit (int privilegeId, User user,
java.lang.Object businessData, java.util.Map context)
評估決策授權策略,返回決策結果。
|
表示對于privilegeId操作,user對于businessData業務數據是否有操作權限。context表示權限判定需要的業務數據,可以為null。
WebMetadminService類,提供如下方法:
static boolean
|
permit (HttpServletRequest req,
int privilegeId, java.lang.Object businessObject)
評估決策授權策略,返回決策結果。
|
static boolean
|
permit (HttpServletRequest req,
int privilegeId, java.lang.Object businessObject,
java.util.Map context)
評估決策授權策略,返回決策結果。
|
WebMetadminService為MetadminService為Web程序封裝,從HttpServletRequest里面取出user,而不用顯式地傳值。
完整JAVADOC請瀏覽:http://www.metadmin.com/doc/javadoc/index.html
示例程序,對刪除員工進行權限判定代碼如下:
if (WebMetadminService.permit(req, Privilege.DELETE_EMPLOYEE,
employee)) {
employeeManager.deleteEmployee(id);
}
employee對象,是根據前臺傳入id參數從數據庫查詢出來的員工對象。
權限邏輯設置
上章例子設置:總公司用戶能查詢所有員工;分公司用戶能查詢本分公司及下屬營業部員工;營業部員工能查詢本營業部員工。
本例將員工刪除權限修改一下:所有用戶只能刪除自己所在機構的員工,也就是總公司用戶只能刪除總公司員工;分公司用戶只能刪除分公司員工;營業部用戶只能刪除營業部員工。
Metadmin對于這樣的權限邏輯,只要新建“所有用戶”用戶分類,及“用戶所在機構員工”業務數據分類,然后將該2種分類配對設置該“刪除員工”權限即可。
首先,創建“所有用戶”用戶分類,打開設計器:http://localhost:8080/mydemo/metadmin/designer
1.
在用戶分類欄,新建分類,輸入名稱為“所有用戶”;
2.
創建固定值a,設置其值為1;
3.
在表達式定義處,定義Binary表達式“a=a”。
這樣,所有用戶都會滿足該條件。
然后,創建“用戶所在機構員工”業務數據分類,打開設計器:http://localhost:8080/mydemo/metadmin/designer
1.
在業務數據分類欄,新建分類,輸入名稱為“用戶所在機構員工”;
2.
創建用戶屬性變量“userCompanyId”,其值等于用戶的companyId屬性;
3.
創建業務數據變量“businessDataCompanyId”,其值等于Employee對象的companyId屬性;
4.
在表達式定義處,定義Binary表達式userCompanyId==businessDataCompanyId。
這樣,只有當user對象和employee對象的companyId屬性相等時,數據才屬于該業務數據分類。如圖示:

然后,將該分類配對設置給刪除員工權限。如圖示:

至此,權限邏輯設置完畢。業務代碼里面集成的權限判斷,將按照該邏輯執行。當權限判斷邏輯發生變化,只要打開設計器重新設計權限邏輯即可。不需要修改代碼,重新發布系統。
posted on 2009-06-23 09:55
細粒度權限管理 閱讀(3476)
評論(3) 編輯 收藏