这篇Java教程基于JDK1.8。教程中的示例和实践不会使用未来发行版中的优化建议。
教程:控制应用程序快速教程
前置教程:创建策略文件
该课程将演示如何使用安全管理器授予或拒绝对应用程序系统资源的访问。该课程也会演示如何进行资源访问,比如运行在安全管理器中的应用程序不允许读写一个文件,除非策略文件中有权限条目予以允许。
该课有如下步骤:
1. 应用自由度
在应用程序运行时,不会自动安装安全管理器。在下一个步骤中,您将看到如何将安全策略应用于本地文件系统上的应用程序,就像应用于下载的沙箱applet一样。但首先,让我们演示应用程序在默认没有安装安全管理器的情况,应用程序可以完全访问资源。
通过复制或下载GetProps.java源代码,在计算机上创建一个名为GetProps.java的文件。
该教程示例假设,如果您使用的是Windows系统,那么将GetProps.java放在C:\Test目录中,如果使用的是UNIX系统,那么将GetProps.java放在~/test目录中。
如同源文件所描述的,这个程序试图获取(读取)属性值,这些属性值包括 “os.name” , “java.version”, “user.home”, 和“java.home”。
现在编译并运行GetProps.java。您应该看到如下输出:
qinzydeMacBook-Pro:jdk-sample qinzy$ java GetProps
About to get os.name property value
The name of your operating system is: Mac OS X
About to get java.version property value
The version of the JVM you are running is: 1.8.0_171
About to get user.home property value
Your user home directory is: /Users/qinzy
About to get java.home property value
Your JRE installation directory is: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre
这表明应用程序被允许访问所有属性值,如下图所示。
2. 如何限制应用
正如您在前面步骤中看到的,Java运行时在运行应用程序时不会自动安装安全管理器。要对本地文件系统上的应用程序与下载的沙箱applet使用相同的安全策略,可以在命令行参数中调用-Djava.security.manager 解释器。
要使用默认的安全管理器执行GetProps应用程序,请键入以下命令:
java -Djava.security.manager GetProps
这是程序的输出:
qinzydeMacBook-Pro:jdk-sample qinzy$ java -Djava.security.manager GetProps
About to get os.name property value
The name of your operating system is: Mac OS X
About to get java.version property value
The version of the JVM you are running is: 1.8.0_171
About to get user.home property value
Caught exception java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.home" "read")
流程如下图所示。
安全敏感属性
Java运行时默认加载一个默认策略文件,并授予代码访问一些常用属性(如“os.name”和“java .version”)的权限。这些属性对安全性不敏感,因此授予这些权限通常不会造成安全风险。
GetProps尝试访问的其他属性是“user.home”和“java.home”,系统策略文件未授予应用读取这些属性的权限。因此,一旦GetProps尝试访问这些属性中的第一个(“user.home”),安全管理器就会阻止访问并报AccessControlException异常。此异常表明当前有效的策略(包含一个或多个策略文件中的条目)不允许读取“user.home”属性。
默认的策略文件
默认的策略文件,位于:
- Windows:java.home\lib\security\java.policy
- UNIX:java.home/lib/security/java.policy
注意java.home表示“java.home”的属性值。该系统属性指定安装JRE的目录。如果JRE安装在Windows上的C:\jdk\jre 目录和UNIX上的/jdk/jre 目录中,则系统策略文件位于:
- Windows:C:\jdk\jre\lib\security\java.policy
- UNIX:/jdk/jre/lib/security/java.policy
3. 设置策略文件并授予需要的权限
此步骤使用策略工具集打开在创建策略文件课程中创建的名为examplepolicy的策略文件。您将添加一个新的策略条目,授予GetProps.class读取“user.home”和“java.home”属性值的权限,如下图所示。
步骤如下:
1. 打开策略文件
请参考上一节 创建策略文件 唯一不同的是CodeBase 选择 GetProps.class 所在的目录
2. 授予需要的权限
点击“添加权限”按钮,打开如下图所示弹出框:
“权限”下拉列表中选择“PropertyPermission”;“目标名称”对应的文本框填“user.home”;“操作”对应的文本框填“read”;如下图所示:
点击“确定”即完成为user.home属性授予read权限,同理,请完成java.home属性的read授权。
3. 保存策略文件
通过“文件”中的“保存”命令保存策略文件;通过“退出”命令退出策略文件工具。
4. 策略文件的影响
现在已经将所需的策略条目添加到examplepolicy策略文件中,在使用安全管理器执行GetProps应用程序时,应该能够读取指定的属性,如下图所示。
无论何时在安全管理器中运行applet或应用程序,默认情况下加载和使用的策略文件都是“security properties file”中指定的策略文件,该文件位于以下目录之一:
- Windows: java.home\lib\security\java.security
- UNIX: java.home/lib/security/java.security
策略文件位置是以下名称对应的属性值:
policy.url.n
其中变量n表示一个数字。在具有以下形式的行中指定每个属性值:
policy.url.n=URL
其中URL是URL规范。例如,默认策略文件(有时分别称为系统和用户策略文件)在“security properties file”中定义为:
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
除了security properties file 中指定策略文件外,还有两种可能的方法可以将examplepolicy文件视为整个策略的一部分。您可以在传递给运行时系统的属性中指定附加策略文件(如方法一所述),或者在 security properties file 中添加一行来指定附加策略文件(如方法二所述)。
方法一
您可以使用 -Djava.security.policy 策略解释器命令行参数,用于指定除安全属性文件中指定的策略文件外还应使用的策略文件。确保您位于包含GetProps.class和examplepolicy的目录中。然后,您可以运行GetProps应用程序,并通过在命令行中键入以下命令将examplepolicy策略文件传递给解释器:
java -Djava.security.manager -Djava.security.policy=examplepolicy GetProps
方法二
您可以在 policy.url.n 中指定n个属性,所有指定的策略文件都将被加载。因此,让java解释器考虑examplepolicy文件的策略条目的一种方法是在 security properties file 中添加一个指定该策略文件的条目。
要修改 security properties file ,请在适合编辑ASCII文本文件的编辑器中打开它。然后在包含policy.url的行之后添加以下行:
policy.url.3=file:${user.home}/test/examplepolicy
运行程序
java -Djava.security.manager GetProps