java學習心得筆記
任何已注冊(經過認證)的用戶都可以創建一個拍賣,但只有創建拍賣的用戶才可以修改這個拍賣。
這意味著任何用戶都可以執行被編寫用來創建 auction 類實例的代碼,但只有擁有該實例的用戶可以執行用來修改它的代碼。通常情況下,創建 auction 實例的用戶就是所有者。這被稱為類實例所有者關系(class instance owner relationship)。
該應用程序的另一個要求可能是:
任何用戶都可以為拍賣創建一個投標,拍賣的所有者可以接受或拒絕任何投標。
再一次,任何用戶都可以執行被編寫用來創建 bid 類實例的代碼,但只有擁有該實例的用戶會被授予修改該實例的許可權。而且,auction 類實例的所有者必須能夠修改相關的 bid 類實例中的接受標志。這意味著在 auction 實例和相應的 bid 實例之間有一種被稱為特定關系(special relationship)的關系。
不幸的是,“java 認證和授權服務”(jaas)— 它是 java 2 平臺的一部分 — 沒有考慮到類實例級訪問控制或者特定關系。在本文中,我們將擴展 jaas 框架使其同時包含這兩者。推動這種擴展的動力是允許我們將訪問控制分離到一個通用的框架,該框架使用基于所有權和特定關系的策略。然后管理員可以在應用程序的生命周期內更改這些策略。
在深入到擴展 jaas 框架之前,我們將重溫一下 java 2 平臺的訪問控制機制。我們將討論策略文件和許可權的使用,并討論 securitymanager 和 accesscontroller 之間的關系。
java 2 平臺中的訪問控制
在 java 2 平臺中,所有的代碼,不管它是本地代碼還是遠程代碼,都可以由策略來控制。策略(policy)由不同位置上的代碼的一組許可權定義,或者由不同的簽發者定義、或者由這兩者定義。許可權允許對資源進行訪問;它通過名稱來定義,并且可能與某些操作關聯在一起。
抽象類 java.security.policy 被用于表示應用程序的安全性策略。缺省的實現由 sun.security.provider.policyfile 提供,在 sun.security.provider.policyfile 中,策略被定義在一個文件中。清單 1 是一個典型策略文件示例:
清單 1. 一個典型的策略文件
// grant these permissions to code loaded from a sample.jar file
// in the c drive and if it is signed by xyz
grant codebase "file:/c:/sample.jar", signedby "xyz" {
// allow socket actions to any host using port 8080
permission .socketpermission "*:8080", "accept, connect,
listen, resolve";
// allows file access (read, write, execute, delete) in
// the user's home directory.
permission java.io.filepermission "${user.home}/-", "read, write,
execute, delete";
};
securitymanager 對 accesscontroller
在標準 jdk 分發版中,控制代碼源訪問的機制缺省情況下是關閉的。在 java 2 平臺以前,對代碼源的訪問都是由 securitymanager 類管理的。securitymanager 是由 java.security.manager 系統屬性啟動的,如下所示:
java -djava.security.manager
在 java 2 平臺中,可以將一個應用程序設置為使用 java.lang.securitymanager 類或者 java.security.accesscontroller 類管理敏感的操作。accesscontroller 在 java 2 平臺中是新出現的。為便于向后兼容,securitymanager 類仍然存在,但把自己的決定提交 accesscontroller 類裁決。securitymanager 和 accesscontroller 都使用應用程序的策略文件確定是否允許一個被請求的操作。清單 2 顯示了 accesscontroller 如何處理 socketpermission 請求:
清單 2. 保護敏感操作
public void somemethod() {
permission permission =
new .socketpermission("localhost:8080", "connect");
accesscontroller.checkpermission(permission);
// sensitive code starts here
socket s = new socket("localhost", 8080);
}
在這個示例中,我們看到 accesscontroller 檢查應用程序的當前策略實現。如果策略文件中定義的任何許可權暗示了被請求的許可權,該方法將只簡單地返回;否則拋出一個 accesscontrolexception 異常。在這個示例中,檢查實際上是多余的,因為缺省套接字實現的構造函數也執行相同的檢查。
在下一部分,我們將更仔細地看一下 accesscontroller 如何與 java.security.policy 實現共同合作安全地處理應用程序請求。
運行中的 accesscontroller
accesscontroller 類典型的 checkpermission(permission p) 方法調用可能會導致下面的一系列操作:
accesscontroller 調用 java.security.policy 類實現的 getpermissions(codesource codesource) 方法。
getpermissions(codesource codesource) 方法返回一個 permissioncollection 類實例,這個類實例代表一個相同類型許可權的集合。
accesscontroller 調用 permissioncollection 類的 implies(permission p) 方法。
接下來,permissioncollection 調用集合中包含的單個 permission 對象的 implies(permission p) 方法。如果集合中的當前許可權對象暗示指定的許可權,則這些方法返回 true,否則返回 false。