這兩個地址是關於這個問題的討論和分析. html
衆所周知,Java語言具備完善的安全框架,從編程語言,編譯器、解釋程序到Java虛擬機,都能確保Java系統不被無效的代碼或敵對的編譯器暗中破壞,基本上,它們保證了Java代碼按預約的規則運做。可是,當咱們須要逾越這些限制時,例如,讀寫文件,監聽和讀寫Socket,退出Java系統等,就必須使用數字簽名或安全策略文件(*.Policy)。
在企業內部網中,本文提出了使用安全策略文件來設置java程序權限的一種簡單的方法。因爲企業內部網中各臺計算機的位置、用途和安全性明確,更適於使用安全策略文件來設置java的權限,軟件的安裝、設置、升級和遷移都很是的方便,而且,還能夠和數字簽名配合使用,更重要的是,能夠細分每一個java程序的權限,使用起來靈活方便。
一. Java中安全策略的概念
Java應用程序環境的安全策略,詳細說明了對於不一樣的代碼所擁有的不一樣資源的許可,它由一個Policy對象來表達。爲了讓applet(或者運行在SecurityManager下的一個應用程序)可以執行受保護的行爲,例如讀寫文件,applet(或Java應用程序)必須得到那項操做的許可,安全策略文件就是用來實現這些許可。
Policy對象可能有多個實體,雖然任什麼時候候只能有一個起做用。當前安裝的Policy對象,在程序中能夠經過調用getPolicy方法獲得,也能夠經過調用setPolicy方法改變。Policy對象評估整個策略,返回一個適當的Permissions對象,詳細說明那些代碼能夠訪問那些資源。
策略文件能夠儲存在無格式的ASCII文件,或Policy類的二進制文件,或數據庫中。本文僅討論無格式的ASCII文件的形式。
二. Policy文件的格式
爲了可以更好地理解下面的內容,建議在閱讀時參照\jdk1.2\jre\lib\security\java.policy文件和\jdk1.2\jre\lib\security\java.security文件的內容。
1. Policy文件的語法格式與說明
一個Policy文件實質上是一個記錄列表,它可能含有一個「keystore」記錄,以及含有零個或多個「grant」記錄。其格式以下:
keystore "some_keystore_url", "keystore_type";
grant [SignedBy "signer_names"] [, CodeBase "URL"] {
Permission permission_class_name
[ "target_name" ] [, "action"] [, SignedBy "signer_names"];
Permission ...};
1.1"keystore"記錄
一個keystore是一個私有密鑰(privatekeys)數據庫和相應的數字簽名,例如X.509證書。Policy文件中可能只有一條keystore記錄(也可能不含有該記錄),它能夠出如今文件中grant記錄之外的任何地方。Policy配置文件中指定的keystores用於尋找grant記錄中指定的、簽名者的公共密鑰(publickeys),若是任何grant記錄指定簽名者(signer_names),那麼,keystore記錄必須出如今policy配置文件中。
"some_keystore_url"是指keystore的URL位置,"keystore_type"是指keystore的類型。第二個選項是可選項,若是沒有指定,該類型則假定由安全屬性文件(java.security)中的"keystore.type"屬性來肯定。keystore類型定義了keystore信息的存儲和數據格式,用於保護keystore中的私有密鑰和keystore完整性的算法。SunMicrosystems支持的缺省類型爲「JKS」。
1.2"grant"記錄
在Policy文件中的每個grant記錄含有一個CodeSource(一個指定的代碼)及其permission(許可)。
Policy文件中的每一條grant記錄遵循下面的格式,以保留字「grant」開頭,表示一條新的記錄的開始,「Permission」是另外一個保留字,在記錄中用來標記一個新的許可的開始。每個grant記錄授予一個指定的代碼(CodeBase)一套許可(Permissions)。
permission_class_name必須是一個合格並存在的類名,例如java.io.FilePermission,不能使用縮寫(例如,FilePermission)。
target_name用來指定目標類的位置,action用於指定目標類擁有的權限。
target_name能夠直接指定類名(能夠是絕對或相對路徑),目錄名,也能夠是下面的通配符:
directory/* 目錄下的全部文件
*當前目錄的全部文件
directory/-目錄下的全部文件,包括子目錄
- 當前目錄下的全部文件,包括子目錄
《ALL FILES》文件系統中的全部文件
對於java.io.FilePermission,action能夠是:
read, write, delete和execute。
對於java.net.SocketPermission,action能夠是:
listen,accept,connect,read,write。
1.3 Policy文件中的屬性擴展(Property Expansion)
屬性擴展與shell中使用的變量擴展相似,它的格式爲:
"${some.property}"
實際使用的例子爲:
permission java.io.FilePermission "${user.home}", "read"; "${user.home}"的值爲"d:\Project",
所以,下面的語句和上面的語句是同樣的:
permission java.io.FilePermission " d:\Project ", "read";
三. 實例
當初始化Policy時,首先裝載系統Policy,而後再增長用戶Policy,若是二者都不存在,則使用缺省的Policy,即原始的沙箱模型。
系統Policy文件的缺省位置爲:
{java.home}/lib/security/java.policy (Solaris)
{java.home}\lib\security\java.policy (Windows)
用戶Policy文件的缺省位置爲:
{user.home}/.java.policy (Solaris)
{user.home}\.java.policy (Windows)
其實,在實際使用中,咱們可能不會象上面介紹的那麼複雜,特別是在不使用數字簽名時。這時,咱們徹底能夠借鑑JDK1.2提供給咱們的現成的\jdk1.2\jre\lib\security\java.policy文件,根據咱們的須要做相應的修改,本文就針對不使用數字簽名狀況詳細說明安全策略文件的用法。
下面,是一個完整的在Windows 95/98/NT下使用的.java.policy文件。在文件中,分別使用註釋的形式說明了每一個「permission」記錄的用途。
// For LanServerTalk.java and LanClientTalk.java
grant {
//對系統和用戶目錄「讀」的權限
permission java.util.PropertyPermission "user.dir", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "java.class.path", "read";
permission java.util.PropertyPermission "user.name", "read";
//對線程和線程組的操做權限
permission java.lang.RuntimePermission "modifyThread";
permission java.lang.RuntimePermission "modifyThreadGroup";
//操做Socket端口的各類權限
permission java.net.SocketPermission "-", "listen";
permission java.net.SocketPermission "-", "accept";
permission java.net.SocketPermission "-", "connect";
permission java.net.SocketPermission "-", "read";
permission java.net.SocketPermission "-", "write";
//讀寫文件的權限
permission java.io.FilePermission "-", "read";
permission java.io.FilePermission "-", "write";
//退出系統的權限,例如System.exit(0)
permission java.lang.RuntimePermission "exitVM";
};
四. java.policy文件的使用
對於windows 95/98/NT,使用.java.policy文件的方法主要有下面兩種。
1. 使用缺省目錄
咱們能夠簡單地將編輯好的.java.policy文件拷貝到windows95/98/NT的HOME目錄,這時,全部的applet(或Java應用程序)可能都擁有某些相同的權限,使用起來簡單,但不靈活(例如:對於java.io.FilePermission,其目標類的target_name必須使用絕對路徑),若是不是在企業內部網中使用,還可能存在必定安全隱患。
2. 在命令行中指定
在命令行,若是咱們但願傳遞一個Policy文件給appletviewer,還可使用"-J-Djava.security.policy"參數來指定policy的位置:
appletviewer -J-Djava.security.
policy=pURL myApplet
pURL爲Policy文件的位置。下面,是一個實際的例子,以當前目錄的.java.policy文件所指定的安全策略運行當前目錄的LanServerTalk.html(文件中裝載並運行LanServerTalk.java):
appletviewer -J-Djava.security.policy
=.java.policy LanServerTalk.html
這種方法使用靈活,特別是做爲一個軟件包在企業內部網中發佈時,安裝、設置和遷移軟件,基本無須修改Policy文件的內容,使用起來至關簡單,並且,安全許可的範圍控制較精細 java