標籤:java安全管理器 securitymanager policy 許可權控制 安全
總的來說,Java安全應該包括兩方面的內容,一是Java平台(即是Java運行環境)的安全性;二是Java語言開發的應用程式的安全性。由於我們不是Java本身語言的制定開發人員,所以第一個安全性不需要我們考慮。其中第二個安全性是我們重點考慮的問題,一般我們可以通過安全管理器機制來完善安全性,安全管理器是安全的實施者,可對此類進行擴充,它提供了加在應用程式上的安全措施,通過配置安全性原則檔案達到對網路、本地檔案和程式其它部分的訪問限制的效果。
Java從應用程式層給我們提供了安全管理機制——安全管理器,每個Java應用都可以擁有自己的安全管理器,它會在運行階段檢查需要保護的資源的存取權限及其它規定的操作許可權,保護系統免受惡意操作攻擊,以達到系統的安全性原則。圖3-1-5-1展示了安全管理器的工作機制,當運行Java程式時,安全管理器會根據policy檔案所描述的策略給程式不同模組分配許可權,假設把應用程式分成了三塊,每塊都有不同的許可權,第一塊有讀取某檔案的許可權,第二塊同時擁有讀取某檔案跟記憶體的許可權,第三塊有監聽socket的許可權。通過這個機制就能很好地控製程序各個部分的各種操作許可權,從應用程式層上為我們提供了安全管理原則。圖3-1-5-2為安全管理器對檔案操作進行管理的工作過程,當應用程式要讀取本地檔案時,securitymanager就會在讀取前進行攔截,判斷是否有讀取此檔案的許可權,如果有則順利讀取,否則將拋出訪問異常。SecurityManager類中提供了很多檢查許可權的方法,例如checkPermission方法會根據安全性原則檔案描述的許可權對操作進行判斷是否有操作許可權,而checkRead方法則用於判斷對檔案存取權限。一旦發現沒有許可權都會拋出安全異常。
圖3-1-5-1 安全管理機制
圖3-1-5-2 檢查操作許可權
一般而言,Java程式啟動時並不會自動啟動安全管理器,可以通過以下兩種方法啟動安全管理器:
① 一種是隱式,啟動預設的安全管理器最簡單的方法就是:直接在啟動命令中添加-Djava.security.manager參數即可。
② 一種是顯式,執行個體化一個java.lang.SecurityManager或繼承它的子類的對象,然後通過System.setSecurityManager()來設定並啟動一個安全管理器。
在啟動安全管理器時可以通過-Djava.security.policy選項來指定安全性原則檔案。如果沒有指定策略檔案的路徑,那麼安全管理器將使用預設的安全性原則檔案,它位於%JAVA_HOME%/jre/lib/security目錄下面的java.policy。需要說明一下的是,=表示這個策略檔案將和預設的策略檔案一同發揮作用;==表示只使用這個策略檔案。policy檔案包含了多個grant語句,每一個grant描述某些代碼擁有某些操作的許可權。在啟動安全管理器時會根據policy檔案產生一個Policy對象,任何時候一個應用程式只能有一個Policy對象。
那麼如何才能實現自己的安全管理器,並且配置許可權呢?下面將通過一個簡單的例子闡明實現步驟,一般可以分為以下兩步:①建立一個SecurityManager子類,並根據需要重寫一些方法。②根據應用程式代碼的許可權需要配置策略檔案。如果使用預設安全管理器則省略第一步,下面用個例子說明安全管理器的使用:
public class SecurityManagerTest {
public static void main(String[] args)throws FileNotFoundException {
System.out.println("SecurityManager: " + System.getSecurityManager());
FileInputStreamfis = new FileInputStream("c:\\protect.txt");
System.out.println(System.getProperty("file.encoding"));
}
}
分下面幾種情況運行程式:
(1) 假如不添加啟動參數直接運行,則相當於沒有啟動安全管理器,SecurityManager列印出來為null,且能正確讀取protect.txt檔案跟file.encoding屬性。
(2) 添加啟動參數-Djava.security.manager-Djava.security.policy=c:/protect.policy,倆參數分別代表啟動預設安全管理器和指明策略設定檔路徑。此時SecurityManager列印出來為不為null,但由於此時protect.policy裡面並沒有做任何授權,所以在讀取檔案的時就拋出AccessControlExcepti on異常。
(3) 在protect.policy檔案添加以下授權語句,
grant {
permissionjava.io.FilePermission "c:/protect.txt", "read";
};
此時SecurityManager不為空白,並且有許可權讀取protect.txt檔案,但最終還是會拋一個AccessControlException異常,因為並沒有許可權讀取file.encoding系統屬性。
(4) 將protect.policy授權語句改為如下:
grant {
permissionjava.io.FilePermission "c:/protect.txt", "read";
permissionjava.util.PropertyPermission "file.encoding", "read";
};
這次讀取檔案跟讀取系統屬性的許可權都有了,程式正常運行,不再拋出安全異常。
由上面幾種情況我們清晰瞭解安全管理器的使用,通過簡單地配置策略檔案能達到應用安全的管理。Java的Permission類是用來定義類所擁有的許可權,Java本身包括了一些 Permission類,如下:
java.security.AllPermission |
所有許可權的集合 |
java.util.PropertyPermission |
系統/環境屬性許可權 |
java.lang.RuntimePermission |
運行時許可權 |
java.net.SocketPermission |
Socket許可權 |
java.io.FilePermission |
檔案許可權,包括讀寫,刪除,執行 |
java.io.SerializablePermission |
序列化許可權 |
java.lang.reflect.ReflectPermission |
反射許可權 |
java.security.UnresolvedPermission |
未解析的許可權 |
java.net.NetPermission |
網路許可權 |
java.awt.AWTPermission |
AWT許可權 |
java.sql.SQLPermission |
資料庫sql許可權 |
java.security.SecurityPermission |
安全控制方面的許可權 |
java.util.logging.LoggingPermission |
日誌控制許可權 |
javax.net.ssl.SSLPermission |
安全連線許可權 |
javax.security.auth.AuthPermission |
認證許可權 |
javax.sound.sampled.AudioPermission |
音頻系統資源的存取權限 |