设置扩展权限

如果安全 Manager生效,则必须满足以下条件才能使任何软件(包括扩展软件)执行对安全敏感的操作:

让我们通过一些示例更详细地研究这些条件。

使用 PrivilegedAction 类

假设您想修改上一课的扩展示例中的RectangleArea类,以将矩形区域写入文件而不是标准输出。但是,写入文件是对安全性敏感的操作,因此,如果您的软件要在安全性 管理 器下运行,则需要将代码标记为特权。您需要执行两个步骤:

如果我们将这些准则应用于RectangleArea类,则我们的类定义将如下所示:

import java.io.*;
import java.security.*;

public final class RectangleArea {
    public static void
    writeArea(final java.awt.Rectangle r) {
        AccessController.
          doPrivileged(new PrivilegedAction() {
            public Object run() {
                try { 
                    int area = r.width * r.height;
                    String userHome = System.getProperty("user.home");
                    FileWriter fw = new FileWriter( userHome + File.separator
                        + "test" + File.separator + "area.txt");
                    fw.write("The rectangle's area is " + area);
                    fw.flush();
                    fw.close();
                } catch(IOException ioe) {
                    System.err.println(ioe);
                }
                return null;
            }
        });
    }
}

此类中的单个方法writeArea计算矩形的面积,并将该面积写入用户主目录下test目录中名为area.txt的文件中。

处理输出文件的安全性敏感语句放在PrivilegedAction的新实例的run方法内。 (注意run要求返回Object实例.返回的对象可以是null.)然后,将新的PrivilegedAction实例作为参数传递给AccessController.doPrivileged的调用。

有关使用doPrivileged的更多信息,请参见 JDK™文档中的特权块的 API

以这种方式将对安全敏感的代码包装在PrivilegedAction对象中是使扩展能够执行对安全敏感的操作的首要要求。第二个要求是:使安全 管理 器授予特权代码适当的权限。

使用安全策略指定权限

运行时生效的安全策略由* policy file *指定。默认策略由 JRE 软件中的文件lib/security/java.policy设置。

该策略文件通过使用* grant *条目为软件分配安全特权。该策略文件可以包含任意数量的授权条目。缺省策略文件具有此授予条目用于已安装的扩展:

grant codeBase "file:${{java.ext.dirs}}/*" {
    permission java.security.AllPermission;
};

此项指定由file:${{java.ext.dirs}}/*指定的目录中的文件将被授予名为java.security.AllPermission的权限。 (请注意,从 Java 6 开始,java.ext.dirs指的是类似于classpath的目录路径,每个目录都可以包含已安装的 extensions.)很难猜测java.security.AllPermission授予已安装的 extensions 所有可能的安全特权。

然后,默认情况下,已安装的扩展没有安全限制。扩展软件可以执行安全敏感的操作,就好像没有安装安全 管理 器一样,前提是安全敏感代码包含在doPrivileged调用中作为参数传递的PrivilegedAction实例中。

要限制授予扩展的特权,您需要修改策略文件。要拒绝所有扩展的所有特权,您只需删除上面的授予条目即可。

并非所有权限都像默认授予的java.security.AllPermission一样全面。删除默认授权条目后,您可以为特定权限 Importing 新的授权条目,包括:

JDK 中的权限文档提供了有关每个权限的详细信息。让我们看看使用 RectangleArea 作为扩展所需的内容。

RectangleArea.writeArea方法需要两个权限:一个用于确定用户主目录的路径,另一个用于写入文件。假设RectangleArea类 Binding 在文件area.jar中,则可以通过将此条目添加到策略文件中来授予写特权:

grant codeBase "file:${java.home}/lib/ext/area.jar" {
    permission java.io.PropertyPermission "user.home",
        "read";
    permission java.io.FilePermission
        "${user.home}${/}test${/}*", "write";
};

此条 ObjectcodeBase "file:${java.home}/lib/ext/area.jar"部分保证此条目指定的任何权限仅适用于area.jarjava.io.PropertyPermission允许访问属性。第一个参数"user.home"命名属性,第二个参数"read"表示可以读取该属性。 (另一个选择是"write".)

java.io.FilePermission允许访问文件。第一个参数"${user.home}${/}test${/}*"表示已授予area.jar权限,以访问用户主目录中test目录中的所有文件。 (请注意,${/}是与平台无关的文件分隔符.)第二个参数表示所授予的文件访问权仅用于写入。 (第二个参数的其他选择是"read""delete""execute".)

Signing Extensions

您可以使用策略文件通过要求扩展由可信实体签名来对授予扩展的权限进行其他限制。 (有关签名和验证 JAR 文件的 Comment,请参阅本教程中的签名 JAR 文件类。)

要允许对扩展或其他软件进行签名验证以及授予权限,策略文件必须包含* keystore 条目*。密钥库条目指定在验证中使用哪个密钥库。密钥库条目具有以下形式

keystore "keystore_url";

URL * keystore_url *是绝对的或相对的。如果是相对的,则 URL 是相对于策略文件的位置的。例如,要使用keytool使用的默认密钥库,请将此条目添加到java\.policy

keystore "file://${user.home}/.keystore";

要表示必须对 extensions 进行签名才能获得安全性特权,请使用signedBy字段。例如,以下条目指示仅当 extensionsarea.jar由密钥库中由别名 Robert 和 Rita 标识的用户签名时,才被授予列出的特权。

grant signedBy "Robert,Rita",
    codeBase "file:${java.home}/lib/ext/area.jar" {
        permission java.io.PropertyPermission
            "user.home", "read";
        permission java.io.FilePermission
            "${user.home}${/}test${/}*", "write";
};

如果省略了codeBase字段(如以下“授予”所示),则将权限授予任何由“ Robert”或“ Rita”签名的软件,包括已安装或下载的 extensions:

grant signedBy "Robert,Rita" {
    permission java.io.FilePermission "*", "write";  
};

有关策略文件格式的更多详细信息,请参阅 JDK 文档中安全架构规范的 3.3.1 节。

首页