總的來說,Java安全應該包括兩方面的内容,一是Java平台(即是Java運作環境)的安全性;二是Java語言開發的應用程式的安全性。由于我們不是Java本身語言的制定開發者,是以第一個安全性不需要我們考慮。其中第二個安全性是我們重點考慮的問題。
一般我們可以通過安全管理器機制來完善安全性,安全管理器SecurityManager是安全的實施者,可對此類進行擴充,它提供了加在應用程式上的安全措施,通過配置安全政策檔案達到對網絡、本地檔案和程式其它部分的通路限制的效果。
Java在應用層為我們提供了安全管理器,每個Java應用都可以擁有自己的安全管理器,它會在運作階段檢查需要保護的資源的通路權限及其它規定的操作權限,保護系統免受惡意操作攻擊,以達到系統的安全政策。如圖展示了安全管理器的工作機制,當運作Java程式時,安全管理器會根據policy檔案所描述的政策給程式不同子產品配置設定權限,假設把應用程式分成了三塊,每塊都有不同的權限,第一塊有讀取某檔案的權限,第二塊同時擁有讀取某檔案跟記憶體的權限,第三塊有監聽socket的權限。通過這個機制就能很好地控制程式各個部分的各種操作權限,從應用層上為我們提供了安全管理政策。
下圖為安全管理器對檔案操作進行管理的工作過程,當應用程式要讀取本地檔案時,securitymanager就會在讀取前進行攔截,判斷是否有讀取此檔案的權限,如果有則順利讀取,否則将抛出通路異常。SecurityManager類中提供了很多檢查權限的方法,例如checkPermission方法會根據安全政策檔案描述的權限對操作進行判斷是否有操作權限,而checkRead方法則用于判斷對檔案通路權限。一旦發現沒有權限都會抛出安全異常。
一般而言,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對象。
那麼如何才能實作自己的安全管理器,并且配置權限呢?下面将通過一個簡單的例子闡明實作步驟,一般可以分為以下兩步:
1. 建立一個SecurityManager子類,并根據需要重寫一些方法。
2. 根據應用程式代碼的權限需要配置政策檔案。如果使用預設安全管理器則省略第一步,下面用個例子說明安全管理器的使用:
分下面幾種情況運作程式:
假如不添加啟動參數直接運作,則相當于沒有啟動安全管理器,SecurityManager列印出來為null,且能正确讀取protect.txt檔案跟file.encoding屬性。
添加啟動參數-Djava.security.manager-Djava.security.policy=c:/protect.policy,倆參數分别代表啟動預設安全管理器和指明政策配置檔案路徑。此時SecurityManager列印出來為不為null,但由于此時protect.policy裡面并沒有做任何授權,是以在讀取檔案的時就抛出AccessControlExcepti on異常。
在protect.policy檔案添加以下授權語句,此時SecurityManager不為空,并且有權限讀取protect.txt檔案,但最終還是會抛一個AccessControlException異常,因為并沒有權限讀取file.encoding系統屬性。
将protect.policy授權語句改為如下,這次讀取檔案跟讀取系統屬性的權限都有了,程式正常運作,不再抛出安全異常。
由上面幾種情況我們清晰了解安全管理器的使用,通過簡單地配置政策檔案能達到應用安全的管理。Java的Permission類是用來定義類所擁有的權限,Java本身包括了一些 Permission類,如下:
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
音頻系統資源的通路權限
========廣告時間========
<a href="http://blog.csdn.net/wangyangzhizhou/article/details/74080321">為什麼寫《Tomcat核心設計剖析》</a>
=========================
歡迎關注: