当你想对Java程序进行权限控制时,可以考虑启用SecurityManager安全管理器,并配置XX.policy文件来达到你想的效果。(想对安全管理器进一步了解,可以阅读《深入Java虚拟机》)
1.启动SecurityManager开关
默认情况下,JVM是不启动安全检查的,所以要想让程序在沙箱中运行,必须将开关打开。打开的方式有两种,一种是在启动运行中追加JVM参数 -Djava.security.manager,还有一种方式是在程序中直接设置:System.setSecurityManager(new SecurityManager());,这两种方式是等价的。
2.JVM自带的java.policy文件
里面定义了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 服务器、读取部分系统属性。相信从字面上大家也能读懂其含义。
在这个类中,我们将对D:/test.txt的文件进行访问,在C:/temp目录用命令行下执行java JavaPolicyTest,可以看到,操作都可以成功。但如果,我们启动了安全管理器时,访问是不成功的。
执行java -Djava.security.manager JavaPolicyTest时,可以看到访问是被拒绝的:
access denied (java.io.FilePermission D:\test.txt read)
access denied (java.io.FilePermission D:\test.txt write)
很明显,由于我们启动了安全检查,这里的操作全部失败。
4.自定义my.policy文件(进行访问仅限控制)
在c:/temp目录下写my.policy文件:
该文件的含义是:位置C:/TEMP目录下的Java程序拥有所有访问权限。
此时,进行测试:
输入命令:java -Djava.security.manager -Djava.security.policy=my.policy JavaPolicyTest
可以看到操作成功:
read-->Fri Jun 29 09:09:03 CST 2012 8306741991113651384
read-->Fri Jun 29 09:09:03 CST 2012 3858861688401833822
read-->Fri Jun 29 09:09:03 CST 2012 1200273480130160113
read-->Fri Jun 29 09:09:03 CST 2012 8757841849132885969
read-->Fri Jun 29 09:09:03 CST 2012 2706431524346322515
read-->Fri Jun 29 09:09:03 CST 2012 3338209174819526164
read-->Fri Jun 29 09:09:03 CST 2012 4303567693339900976
read-->Fri Jun 29 09:09:03 CST 2012 246564543183403482
read-->Fri Jun 29 09:09:03 CST 2012 -5613827692140751148
read-->Fri Jun 29 09:09:03 CST 2012 -2160324389603373039
file read ok
write-->Fri Jun 29 09:41:33 CST 2012 -4466633047452156168
write-->Fri Jun 29 09:41:33 CST 2012 6002365139178242241
write-->Fri Jun 29 09:41:33 CST 2012 -7638920310528629538
write-->Fri Jun 29 09:41:33 CST 2012 5167349606741454313
write-->Fri Jun 29 09:41:33 CST 2012 2958827128287814608
write-->Fri Jun 29 09:41:33 CST 2012 -5743066306268526126
write-->Fri Jun 29 09:41:33 CST 2012 -7794828514725883971
write-->Fri Jun 29 09:41:33 CST 2012 7382498395857317067
write-->Fri Jun 29 09:41:33 CST 2012 7040217825519914232
write-->Fri Jun 29 09:41:33 CST 2012 -1544415070373588605
file write ok
由于我分配的是AllPermission,所以全部操作都能成功。
1.启动SecurityManager开关
默认情况下,JVM是不启动安全检查的,所以要想让程序在沙箱中运行,必须将开关打开。打开的方式有两种,一种是在启动运行中追加JVM参数 -Djava.security.manager,还有一种方式是在程序中直接设置:System.setSecurityManager(new SecurityManager());,这两种方式是等价的。
2.JVM自带的java.policy文件
Java.policy文件位于%JAVA_HOME%/ jre/lib/security/下,默认内容如下:
里面定义了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 服务器、读取部分系统属性。相信从字面上大家也能读懂其含义。
3.先写个测试例子:JavaPolicyTest.java(将其放在C:/TEMP目录下)
在这个类中,我们将对D:/test.txt的文件进行访问,在C:/temp目录用命令行下执行java JavaPolicyTest,可以看到,操作都可以成功。但如果,我们启动了安全管理器时,访问是不成功的。
执行java -Djava.security.manager JavaPolicyTest时,可以看到访问是被拒绝的:
access denied (java.io.FilePermission D:\test.txt read)
access denied (java.io.FilePermission D:\test.txt write)
很明显,由于我们启动了安全检查,这里的操作全部失败。
4.自定义my.policy文件(进行访问仅限控制)
在c:/temp目录下写my.policy文件:
该文件的含义是:位置C:/TEMP目录下的Java程序拥有所有访问权限。
此时,进行测试:
输入命令:java -Djava.security.manager -Djava.security.policy=my.policy JavaPolicyTest
可以看到操作成功:
read-->Fri Jun 29 09:09:03 CST 2012 8306741991113651384
read-->Fri Jun 29 09:09:03 CST 2012 3858861688401833822
read-->Fri Jun 29 09:09:03 CST 2012 1200273480130160113
read-->Fri Jun 29 09:09:03 CST 2012 8757841849132885969
read-->Fri Jun 29 09:09:03 CST 2012 2706431524346322515
read-->Fri Jun 29 09:09:03 CST 2012 3338209174819526164
read-->Fri Jun 29 09:09:03 CST 2012 4303567693339900976
read-->Fri Jun 29 09:09:03 CST 2012 246564543183403482
read-->Fri Jun 29 09:09:03 CST 2012 -5613827692140751148
read-->Fri Jun 29 09:09:03 CST 2012 -2160324389603373039
file read ok
write-->Fri Jun 29 09:41:33 CST 2012 -4466633047452156168
write-->Fri Jun 29 09:41:33 CST 2012 6002365139178242241
write-->Fri Jun 29 09:41:33 CST 2012 -7638920310528629538
write-->Fri Jun 29 09:41:33 CST 2012 5167349606741454313
write-->Fri Jun 29 09:41:33 CST 2012 2958827128287814608
write-->Fri Jun 29 09:41:33 CST 2012 -5743066306268526126
write-->Fri Jun 29 09:41:33 CST 2012 -7794828514725883971
write-->Fri Jun 29 09:41:33 CST 2012 7382498395857317067
write-->Fri Jun 29 09:41:33 CST 2012 7040217825519914232
write-->Fri Jun 29 09:41:33 CST 2012 -1544415070373588605
file write ok
由于我分配的是AllPermission,所以全部操作都能成功。