Java程序访问权限控制(policy文件)

当你想对Java程序进行权限控制时,可以考虑启用SecurityManager安全管理器,并配置XX.policy文件来达到你想的效果。(想对安全管理器进一步了解,可以阅读《深入Java虚拟机》)
1.启动SecurityManager开关
默认情况下,JVM是不启动安全检查的,所以要想让程序在沙箱中运行,必须将开关打开。打开的方式有两种,一种是在启动运行中追加JVM参数 -Djava.security.manager,还有一种方式是在程序中直接设置:System.setSecurityManager(new SecurityManager());,这两种方式是等价的。
2.JVM自带的java.policy文件

java.policy文件位于%JAVA_HOME%/ jre/lib/security/下,默认内容如下:

// Standard extensions get all permissions by default
 
grant codeBase "file<img src="%5C%22static/image/smiley/default/shy.gif%5C%22" smilieid="\"8\"" alt="\"\"" border="\"0\"">{{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 "http://java.sun.com/notes" for more information.
        permission java.lang.RuntimePermission "stopThread";
 
        // allows anyone to listen on un-privileged ports
        permission java.net.SocketPermission "localhost:1024-", "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 服务器、读取部分系统属性。相信从字面上大家也能读懂其含义。

3.先写个测试例子:JavaPolicyTest.java(将其放在C:/TEMP目录下)

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) {
                File file = new File("D:/test.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();
        }
}

在这个类中,我们将对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文件:

grant codeBase "file:/C:/TMP/*" {
    permission java.security.AllPermission;
};

该文件的含义是:位置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,所以全部操作都能成功。

你可能感兴趣的:(policy)