基本情況
Policy對象可能有多個實體,雖然任何時候只能有一個起作用。當前安裝的Policy對象,在程序中可以通過調用getPolicy方法得到,也可以通過調用setPolicy方法改變。Policy對象評估整個策略,返回一個適當的Permissions對象,詳細說明哪些代碼可以訪問哪些資源。
策略文件可以儲存在無格式的ASCII文件或Policy類的二進制文件或數據庫中
2.JVM自帶的java.policy文件
路徑:%JAVA_HOME%/ jre/lib/security/
// Standard extensions get all permissions by default
grant codeBase "file:${{java.ext.dirs}}/*" {
permission java.security.AllPermission;
};
// default permissions granted to all domains
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See the API specification of java.lang.Thread.stop() for more
// information.
permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on dynamic ports
permission java.net.SocketPermission "localhost:0", "listen";
// "standard" properies that can be read by anyone
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
};
文件定義了JAVA程序默認的權限,第一個grant定義了系統屬性${{java.ext.dirs}}路徑下的所有的class及jar(/* 號表示所有class和jar,如果只是/則表示所有class但不包括jar)擁有所有的操作權限 (java.security.AllPermission),java.ext.dirs對應路徑為%JAVA_HOME%/jre/lib/ext目 錄,而第二個grant后面定義了所有JAVA程序都擁有的權限,包括停止線程、啟動Socket 服務器、讀取部分系統屬性。相信從字面上大家也能讀懂其含義。
自定義權限文件
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
public class JavaPolicyTest {
public static void main(String[] args) {
//System.setSecurityManager(new SecurityManager());
File file = new File("input.txt");
try {
read(file);
System.out.println("file read ok");
} catch (Throwable e) {
System.out.println(e.getMessage());
}
try {
write(file);
System.out.println("file write ok");
} catch (Throwable e) {
System.out.println(e.getMessage());
}
}
private static void read(File file) throws Throwable {
InputStream in = null;
BufferedReader reader = null;
try {
in = new FileInputStream(file);
reader = new BufferedReader(new InputStreamReader(in));
String temp = null;
while ((temp = reader.readLine()) != null) {
System.out.println("read-->" + temp);
}
} catch (Throwable e) {
throw e;
} finally {
if (in != null) {
in.close();
}
if (reader != null) {
reader.close();
}
}
}
private static void write(File file) throws Throwable {
FileWriter fw = new FileWriter(file);
for (int i = 0; i < 10; i++) {
String temp = new java.util.Date() + " "
+ new java.util.Random().nextLong();
System.out.println("write-->" + temp);
fw.write(temp + "\r\n");
}
fw.flush();
fw.close();
}
}
運行結果:
read-->Fri Apr 22 11:39:57 CST 2016 -262531709744128099
read-->Fri Apr 22 11:39:57 CST 2016 985665727509211506
read-->Fri Apr 22 11:39:57 CST 2016 9196200500121727384
read-->Fri Apr 22 11:39:57 CST 2016 -6067897100699200127
read-->Fri Apr 22 11:39:57 CST 2016 3348381817560681737
read-->Fri Apr 22 11:39:57 CST 2016 -7887731814430357730
read-->Fri Apr 22 11:39:57 CST 2016 5299018159517640380
read-->Fri Apr 22 11:39:57 CST 2016 3386262927307792578
read-->Fri Apr 22 11:39:57 CST 2016 4547128732633457509
read-->Fri Apr 22 11:39:57 CST 2016 7066979202206165695
file read ok
write-->Fri Apr 22 11:43:44 CST 2016 -2208906386445481124
write-->Fri Apr 22 11:43:44 CST 2016 6234100627825921321
write-->Fri Apr 22 11:43:44 CST 2016 -351090903219305836
write-->Fri Apr 22 11:43:44 CST 2016 2477244353196532629
write-->Fri Apr 22 11:43:44 CST 2016 8907337408381452919
write-->Fri Apr 22 11:43:44 CST 2016 4447767369770091795
write-->Fri Apr 22 11:43:44 CST 2016 6167989055550024755
write-->Fri Apr 22 11:43:44 CST 2016 -6455765343100482150
write-->Fri Apr 22 11:43:44 CST 2016 3880608459363665649
write-->Fri Apr 22 11:43:44 CST 2016 1958120961079232085
file write oK
是的 ,運行沒有任何問題,但是我們加上System.setSecurityManager(new SecurityManager());
運行結果:
access denied ("java.io.FilePermission" "input.txt" "read")
access denied ("java.io.FilePermission" "input.txt" "write")
我們看到輸出結果就明白啦,是的我們啟動了安全管理器,它使用了系統默認的策略文件,對文件訪問是需要權限的。
自定義一個myTest.policy文件
grant codeBase "/users/zhangpan/Documents/project/web/StudyDemo/input.txt" {
permission java.security.AllPermission;
};
在測試代碼添加:
System.setProperty("java.security.policy", "myTest.policy");
System.setSecurityManager(new SecurityManager());
運行就通過了。