| 導購 | 订阅 | 在线投稿
分享
 
 
 

動態Proxy與Java ACL用戶訪問控制機制實現

來源:互聯網  2008-06-04 06:44:50  評論

用戶訪問控制(Access control )機制總是圍繞粗粒度和細粒度兩個方面來討論:

粗粒度控制:可以規定訪問整個對象或對象群的某個層,而細粒度控制則總是在方法或屬性層進行控制,比如:

允許一個文件爲只讀是屬于粗粒度控制,而允許對這個文件某行有寫操作則屬于細粒度控制。

一個好的用戶控制機制當然既允許粗粒度也允許細粒度控制,在Jive中我們看到是使用Proxy來達到這個目的,但是我們也發現,由于需要對每個類都要進行細粒度控制,所以必然對每個類都要做一個Proxy類,這樣帶來了很多Proxy類,如ForumProxy ForumThreadProxy ForumFactoryProxy等,無形增加了系統複雜性。

使用動態Proxy可以很好的解決這個問題。再結合java.security.acl的ACL機制,我們就可以靈活地實現粗粒度和細粒度的雙重控制。

當一個用戶login後,我們就要在內存中爲其建立相應的授權訪問機制,使用java.security.acl可以很方便的建立這樣一個安全系統。

首先任何一個對象都應該有個基本屬性:擁有者 或擁有者所屬組(Windows中每個目錄安全描述符都由4部分構成:對象的創建者、對象所屬的組、自由存取控制和系統存取控制)。

1. Java acl開始第一步是建立一個主體 Principal,其中SecurityOwner是主體的擁有者: private static final Principal _securityOwner = new PrincipalImpl("SecurityOwner");

2. 當用戶login進來時,他帶有兩個基本數據:訪問密碼和他要訪問的對象ApplicationName。首先驗證用戶名和密碼,然後從數據庫中取出其權限數據,建立Permission,這裏使用Feature繼承了Permission,在Feature中定義了有關權限的細節數據(如讀 寫 刪)。

// 取出用戶和被訪問對象之間的權限關系,這種權限關系可能不只一個,也就是說,用戶

//可能對被訪問對象擁有讀 寫 刪等多個權限,將其打包在Hasbtable中。

Hashtable features = loadFeaturesForUser(sApplicationName, sUserID);

3. 創建一個用戶對象

User user = new UserImpl(sUserID, new Hashtable() );

4. 爲這個用戶創建一個活動的acl entry

addAclEntry( user, features);

其中最關鍵的是第四步addAclEntry,我們看看其如何實現的:

// 爲這個用戶創建一個新的Acl entry

AclEntry newAclEntry = new AclEntryImpl( user);

//遍曆Hashtable features,將其中多種權限加入:

....

feature = (Feature) hFeatures.get(keyName);

newAclEntry.addPermission( feature );

....

最後也要加入主體擁有者SecurityOwner

這樣一個安全體系就已經建立完成。

當你在系統中要檢驗某個用戶使用擁有某個權限,如讀的權利時,只要acl.checkPermission(user, feature )就可以,acl是ACL的一個實例,這樣權限檢查就交給java.security.acl.ACL 去處理了。

有了ACL機制後,我們就可以在我們系統中使用動態Proxy模式來對具體對象或方法進行控制,比如,我們有一個Report類,有些用戶可以讀,有些用戶可以寫(哪些用戶可以讀 哪些用戶可以寫,已經在上面ACL裏部署完成)。

從Java 1.3開始, Sun提供了Dynamic Proxy API.爲了使動態Proxy能夠工作,第一你必須有一個Proxy接口,還要有一個繼承InvocationHandler的Proxy類。

在下面的例子中,我們設定有三種用戶:普通人;雇員;經理.權限是這樣:普通人可以讀報告;雇員和經理可以修改報告。

按通常思維,我們對于讀權限,我們設計一個具備讀的角色類:

public interface IpersonRO {

public String getName();

public String getAddress();

public String getPhoneNumber();

}

類裏面都是讀的方法,這是一種粗粒度訪問控制,也就是說把讀寫權限只落實到類(對象)上,這樣的話,我們還要爲寫的角色再建一個類,很顯然這不是一個很好的方法,使用動態proxy+acl就可以實現很好的細粒度控制。

public class ReportProxy implements InvocationHandler

{

private Map map;

public static Object newInstance(Map map,Class[] interfaces)

{

return Proxy.newProxyInstance(map.getClass().getClassLoader(), interfaces,new ReportProxy(map));

}

public ReportProxy(Map map)

{

this.map = map;

}

public Object invoke(Object proxy, Method m, Object[] args) throws Throwable

{

Object result;

String methodName = m.getName();

if (methodName.startsWith("get"))

{

if (!acl.checkPermission(user, "read")) return null;

String name = methodName.substring(

methodName.indexOf("get")+3);

return map.get(name);

}

else if (methodName.startsWith("set"))

{

if (!acl.checkPermission(user, "write")) return null;

String name = methodName.substring(

methodName.indexOf("set")+3);

map.put(name, args[0]);

return null;

}

else if (methodName.startsWith("is"))

{

if (!acl.checkPermission(user, "read")) return null;

String name = methodName.substring(

methodName.indexOf("is")+2);

return(map.get(name));

}

return null;

}

}

用戶訪問控制(Access control )機制總是圍繞粗粒度和細粒度兩個方面來討論: 粗粒度控制:可以規定訪問整個對象或對象群的某個層,而細粒度控制則總是在方法或屬性層進行控制,比如: 允許一個文件爲只讀是屬于粗粒度控制,而允許對這個文件某行有寫操作則屬于細粒度控制。 一個好的用戶控制機制當然既允許粗粒度也允許細粒度控制,在Jive中我們看到是使用Proxy來達到這個目的,但是我們也發現,由于需要對每個類都要進行細粒度控制,所以必然對每個類都要做一個Proxy類,這樣帶來了很多Proxy類,如ForumProxy ForumThreadProxy ForumFactoryProxy等,無形增加了系統複雜性。 使用動態Proxy可以很好的解決這個問題。再結合java.security.acl的ACL機制,我們就可以靈活地實現粗粒度和細粒度的雙重控制。 當一個用戶login後,我們就要在內存中爲其建立相應的授權訪問機制,使用java.security.acl可以很方便的建立這樣一個安全系統。 首先任何一個對象都應該有個基本屬性:擁有者 或擁有者所屬組(Windows中每個目錄安全描述符都由4部分構成:對象的創建者、對象所屬的組、自由存取控制和系統存取控制)。 1. Java acl開始第一步是建立一個主體 Principal,其中SecurityOwner是主體的擁有者: private static final Principal _securityOwner = new PrincipalImpl("SecurityOwner"); 2. 當用戶login進來時,他帶有兩個基本數據:訪問密碼和他要訪問的對象ApplicationName。首先驗證用戶名和密碼,然後從數據庫中取出其權限數據,建立Permission,這裏使用Feature繼承了Permission,在Feature中定義了有關權限的細節數據(如讀 寫 刪)。 // 取出用戶和被訪問對象之間的權限關系,這種權限關系可能不只一個,也就是說,用戶 //可能對被訪問對象擁有讀 寫 刪等多個權限,將其打包在Hasbtable中。 Hashtable features = loadFeaturesForUser(sApplicationName, sUserID); 3. 創建一個用戶對象 User user = new UserImpl(sUserID, new Hashtable() ); 4. 爲這個用戶創建一個活動的acl entry addAclEntry( user, features); 其中最關鍵的是第四步addAclEntry,我們看看其如何實現的: // 爲這個用戶創建一個新的Acl entry AclEntry newAclEntry = new AclEntryImpl( user); //遍曆Hashtable features,將其中多種權限加入: .... feature = (Feature) hFeatures.get(keyName); newAclEntry.addPermission( feature ); .... 最後也要加入主體擁有者SecurityOwner 這樣一個安全體系就已經建立完成。 當你在系統中要檢驗某個用戶使用擁有某個權限,如讀的權利時,只要acl.checkPermission(user, feature )就可以,acl是ACL的一個實例,這樣權限檢查就交給java.security.acl.ACL 去處理了。 有了ACL機制後,我們就可以在我們系統中使用動態Proxy模式來對具體對象或方法進行控制,比如,我們有一個Report類,有些用戶可以讀,有些用戶可以寫(哪些用戶可以讀 哪些用戶可以寫,已經在上面ACL裏部署完成)。 從Java 1.3開始, Sun提供了Dynamic Proxy API.爲了使動態Proxy能夠工作,第一你必須有一個Proxy接口,還要有一個繼承InvocationHandler的Proxy類。 在下面的例子中,我們設定有三種用戶:普通人;雇員;經理.權限是這樣:普通人可以讀報告;雇員和經理可以修改報告。 按通常思維,我們對于讀權限,我們設計一個具備讀的角色類: public interface IpersonRO { public String getName(); public String getAddress(); public String getPhoneNumber(); } 類裏面都是讀的方法,這是一種粗粒度訪問控制,也就是說把讀寫權限只落實到類(對象)上,這樣的話,我們還要爲寫的角色再建一個類,很顯然這不是一個很好的方法,使用動態proxy+acl就可以實現很好的細粒度控制。 public class ReportProxy implements InvocationHandler { private Map map; public static Object newInstance(Map map,Class[] interfaces) { return Proxy.newProxyInstance(map.getClass().getClassLoader(), interfaces,new ReportProxy(map)); } public ReportProxy(Map map) { this.map = map; } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Object result; String methodName = m.getName(); if (methodName.startsWith("get")) { if (!acl.checkPermission(user, "read")) return null; String name = methodName.substring( methodName.indexOf("get")+3); return map.get(name); } else if (methodName.startsWith("set")) { if (!acl.checkPermission(user, "write")) return null; String name = methodName.substring( methodName.indexOf("set")+3); map.put(name, args[0]); return null; } else if (methodName.startsWith("is")) { if (!acl.checkPermission(user, "read")) return null; String name = methodName.substring( methodName.indexOf("is")+2); return(map.get(name)); } return null; } }
󰈣󰈤
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
王朝網路微信公眾號
微信掃碼關註本站公眾號 wangchaonetcn
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有