java學(xué)習(xí)心得筆記
任何已注冊(cè)(經(jīng)過認(rèn)證)的用戶都可以創(chuàng)建一個(gè)拍賣,但只有創(chuàng)建拍賣的用戶才可以修改這個(gè)拍賣。
這意味著任何用戶都可以執(zhí)行被編寫用來創(chuàng)建 auction 類實(shí)例的代碼,但只有擁有該實(shí)例的用戶可以執(zhí)行用來修改它的代碼。通常情況下,創(chuàng)建 auction 實(shí)例的用戶就是所有者。這被稱為類實(shí)例所有者關(guān)系(class instance owner relationship)。
該應(yīng)用程序的另一個(gè)要求可能是:
任何用戶都可以為拍賣創(chuàng)建一個(gè)投標(biāo),拍賣的所有者可以接受或拒絕任何投標(biāo)。
再一次,任何用戶都可以執(zhí)行被編寫用來創(chuàng)建 bid 類實(shí)例的代碼,但只有擁有該實(shí)例的用戶會(huì)被授予修改該實(shí)例的許可權(quán)。而且,auction 類實(shí)例的所有者必須能夠修改相關(guān)的 bid 類實(shí)例中的接受標(biāo)志。這意味著在 auction 實(shí)例和相應(yīng)的 bid 實(shí)例之間有一種被稱為特定關(guān)系(special relationship)的關(guān)系。
不幸的是,“java 認(rèn)證和授權(quán)服務(wù)”(jaas)— 它是 java 2 平臺(tái)的一部分 — 沒有考慮到類實(shí)例級(jí)訪問控制或者特定關(guān)系。在本文中,我們將擴(kuò)展 jaas 框架使其同時(shí)包含這兩者。推動(dòng)這種擴(kuò)展的動(dòng)力是允許我們將訪問控制分離到一個(gè)通用的框架,該框架使用基于所有權(quán)和特定關(guān)系的策略。然后管理員可以在應(yīng)用程序的生命周期內(nèi)更改這些策略。
在深入到擴(kuò)展 jaas 框架之前,我們將重溫一下 java 2 平臺(tái)的訪問控制機(jī)制。我們將討論策略文件和許可權(quán)的使用,并討論 securitymanager 和 accesscontroller 之間的關(guān)系。
java 2 平臺(tái)中的訪問控制
在 java 2 平臺(tái)中,所有的代碼,不管它是本地代碼還是遠(yuǎn)程代碼,都可以由策略來控制。策略(policy)由不同位置上的代碼的一組許可權(quán)定義,或者由不同的簽發(fā)者定義、或者由這兩者定義。許可權(quán)允許對(duì)資源進(jìn)行訪問;它通過名稱來定義,并且可能與某些操作關(guān)聯(lián)在一起。
抽象類 java.security.policy 被用于表示應(yīng)用程序的安全性策略。缺省的實(shí)現(xiàn)由 sun.security.provider.policyfile 提供,在 sun.security.provider.policyfile 中,策略被定義在一個(gè)文件中。清單 1 是一個(gè)典型策略文件示例:
清單 1. 一個(gè)典型的策略文件
// 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 對(duì) accesscontroller
在標(biāo)準(zhǔn) jdk 分發(fā)版中,控制代碼源訪問的機(jī)制缺省情況下是關(guān)閉的。在 java 2 平臺(tái)以前,對(duì)代碼源的訪問都是由 securitymanager 類管理的。securitymanager 是由 java.security.manager 系統(tǒng)屬性啟動(dòng)的,如下所示:
java -djava.security.manager
在 java 2 平臺(tái)中,可以將一個(gè)應(yīng)用程序設(shè)置為使用 java.lang.securitymanager 類或者 java.security.accesscontroller 類管理敏感的操作。accesscontroller 在 java 2 平臺(tái)中是新出現(xiàn)的。為便于向后兼容,securitymanager 類仍然存在,但把自己的決定提交 accesscontroller 類裁決。securitymanager 和 accesscontroller 都使用應(yīng)用程序的策略文件確定是否允許一個(gè)被請(qǐng)求的操作。清單 2 顯示了 accesscontroller 如何處理 socketpermission 請(qǐng)求:
清單 2. 保護(hù)敏感操作
public void somemethod() {
permission permission =
new .socketpermission("localhost:8080", "connect");
accesscontroller.checkpermission(permission);
// sensitive code starts here
socket s = new socket("localhost", 8080);
}
在這個(gè)示例中,我們看到 accesscontroller 檢查應(yīng)用程序的當(dāng)前策略實(shí)現(xiàn)。如果策略文件中定義的任何許可權(quán)暗示了被請(qǐng)求的許可權(quán),該方法將只簡(jiǎn)單地返回;否則拋出一個(gè) accesscontrolexception 異常。在這個(gè)示例中,檢查實(shí)際上是多余的,因?yàn)槿笔√捉幼謱?shí)現(xiàn)的構(gòu)造函數(shù)也執(zhí)行相同的檢查。
在下一部分,我們將更仔細(xì)地看一下 accesscontroller 如何與 java.security.policy 實(shí)現(xiàn)共同合作安全地處理應(yīng)用程序請(qǐng)求。
運(yùn)行中的 accesscontroller
accesscontroller 類典型的 checkpermission(permission p) 方法調(diào)用可能會(huì)導(dǎo)致下面的一系列操作:
accesscontroller 調(diào)用 java.security.policy 類實(shí)現(xiàn)的 getpermissions(codesource codesource) 方法。
getpermissions(codesource codesource) 方法返回一個(gè) permissioncollection 類實(shí)例,這個(gè)類實(shí)例代表一個(gè)相同類型許可權(quán)的集合。
accesscontroller 調(diào)用 permissioncollection 類的 implies(permission p) 方法。
接下來,permissioncollection 調(diào)用集合中包含的單個(gè) permission 對(duì)象的 implies(permission p) 方法。如果集合中的當(dāng)前許可權(quán)對(duì)象暗示指定的許可權(quán),則這些方法返回 true,否則返回 false。