基本情况
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());
运行就通过了。