您的位置:首页 > 编程语言 > Java开发

JAVA策略文件简介(中)

2011-12-14 11:33 239 查看
五、策略文件语法
  策略配置文件用于对特定的代码指定一定的权限。为了使 applet(或在安全管理器下运行的应用程序)能够执行受保护的动作(例如读写文件),必须向 applet(或应用程序)授予进行该动作的权限。在缺省
Policy 实现中,必须由策略配置文件中的 grant 项授予该权限。唯一的例外是:代码对位于与它自身同一 (URL) 位置并且对那一位置子目录下的文件总是自动拥有读权限,而无需授予明确的权限。策略配置文件主要包含授权项列表。其中可能包含“keystore”(密钥仓库)项及零个或多个“grant”(授权)项。
其基本语法如下:

keystore "some_keystore_url", 
"keystore_type";

grant [SignedBy "signer_names"] [, CodeBase
"URL"] [,principal principal_class_name "principal_name",]{
Permission permission_class_name 
[ "target_name" ] 
[, "action"] [, SignedBy "signer_names"];
Permission ...
};

5.1、Keystore项

         keystore是存放私钥及相关数字证书(例如验证对应的公钥的 X.509 证书链)的数据库。keytool 实用程序 (for Solaris) (for Windows) 用于创建和管理密钥仓库。策略配置文件中所指定的 keystore用于查找在该文件的授权项中所指定的签名人公钥。如果某一授权项指定了签名人别名,则在策略配置文件中需要指明包含该签名人的公钥的keystore文件。 
目前,在策略文件中只能有一个 keystore 项(第一项后的其它 keystore 项将被忽略),且该项可位于文件授权项以外的任何位置。其语法如下所示: 
    keystore "some_keystore_url", "keystore_type";
其中“some_keystore_url”指定密钥仓库的 URL 位置,而“keystore_type”指定密钥仓库的类型。 
URL是相对于策略文件位置而言。因此,如果在安全属性文件中按以下方式指定策略文件: 
    policy.url.1=http://foo.bar.com/fum/some.policy
如果该策略文件中含有以下项: 
    keystore "robin.keystore";
就会从下列位置加载keystore文件:http://foo.bar.com/fum/robin.keystore
当然URL也可以是绝对 URL,比如上面可以直接用:http://foo.bar.com/fum/robin.keystore。        
      keystore type 定义密钥仓库信息的存储和数据格式,同时也定义用于保护密钥仓库中私钥及密钥仓库自身完整性的算法。Sun Microsystems 所支持的缺省类型是名为“JKS”的专用密钥仓库类型。因此,如果密钥仓库类型属于“JKS”,就无需在 keystore 项中加以指定。 

5.2、授权项

      通常认为执行代码来自于某“代码源”(由 CodeSource 类型的对象表示)。代码源不仅包含代码的源位置 (URL),而且还包括代码的签名者。我可以通过keystore中的公钥/私钥对的别名来唯一标识一个签名者。因此这里用公钥/私钥的别名来代表签名者。 
每个授权项包括一个或多个“权限项”,前面为可选 codeBase 和 signedBy 名字/值对,用于指定要授予权限的代码。
授权项的基本格式如下所示: 
  grant signedBy "signer_names", codeBase "URL"
{
    permission permission_class_name "target_name", "action",
        signedBy "signer_names";
    ....
    permission permission_class_name "target_name", "action",
        signedBy "signer_names";
  };
signedBy "signer_names"和codeBase "URL" 为可选域,其间的顺序无关紧要。
当他们同时存在时,表示的是与的关系。
signer_names表示存储在keystore文件中的签名者的公钥/私钥对的别名。公钥用于验证代码上的数字签名。关于数字签名请参照
Java的数字签名和数字证书》和《数字签名简介
signer_names可以是由逗号分隔的多个公钥/私钥对的别名。
例如“Adam,Eve,Charles”,其含义为“Adam,Eve 和 Charles 都进行了签名的代码”;它们之间的关系是 AND(与)而不是OR(或)的关系。
signedBy "signer_names"域可选,这是如果省略该域,则表示“任何签名人”。代码的权限与是否有签名或由谁签名都没有关系。 
codeBase "URL"域 表示的是向来自 "URL"位置的代码赋予一定的权限。
codeBase "URL"域也是可选,这是如果省略该域,则表示“代码的权限与代码来源于何处没有任何关系。 
"URL"是URL,因此应该始终用正斜杠(而不要用反斜杠)作为目录分隔符,即使代码源实际在
Windows 系统上。这样,如果 Windows 系统上代码的源位置实际上是C:\somepath\api\,则 codeBase 策略项的外观将如下所示: 
    grant codeBase "file:/C:/somepath/api/" {
      ...
    }
"URL"的准确含义要取决于最后的字符。以“/”结尾的codeBase
将匹配指定目录下的所有类文件(非 JAR 文件);以“/*”结尾的 codeBase 将匹配该目录下的所有文件(类文件和
JAR 文件);以“/-”结尾的codeBase 将匹配该目录下的所有文件(类文件和 JAR 文件)及该目录下子目录中的所有文件,直接以目录名结尾的应该同于“/”结尾的。
principal principal_class_name "principal_name"的具体含义暂时不清楚。

A principal value specifies a class_name/principal_name pair which must be present within the executing threads principal set. The principal set is associated with the executing code by way of a Subject. The
principal field is optional in that, if it is omitted, it signifies "any principals".
下面是一个 principal-based 条目.

 grant principal javax.security.auth.x500.X500Principal "cn=Alice" {
      permission java.io.FilePermission "/home/Alice", "read, write";
 };
表示允许任何有特征 X500Principal, "cn=Alice" 的客户代码读写 "/home/Alice".

Note on KeyStore Alias Replacement:
If the principal class_name/principal_name pair is specified as a single quoted string, it is treated as a keystore alias. The keystore is consulted and queried (via the alias)
for an X509 Certificate. If one is found, the principal class_name is automatically treated asjavax.security.auth.x500.X500Principal, and the principal_name
is automatically treated as the subject distinguished name from the certificate. If an X509 Certificate mapping is not found, the entire grant entry is ignored.关于此的使用请见后文的示例10

5.3、权限项

如上述,权限的基本语法如下:

    permission permission_class_name "target_name",
"action", signedBy "signer_names";

权限项必须以 permission 开头。
permission_class_name是必须的,它是代表特定的权限类(例如 java.io.FilePermission 或 java.lang.RuntimePermission)。 
"target_name"
对于许多权限类型而言都是必需的,例如对于java.io.FilePermission,则需要指定文件的地址。 对于诸如 java.lang.RuntimePermission 等权限类型则为可选项:
"action" 对于许多权限类型而言都是必需的,例如 java.io.FilePermission(指定允许何种类型的文件访问权限)。 对于诸如 java.lang.RuntimePermission 等权限类型则为可选项。
权限项的 signedBy "signer_names";为可选项,一般很少用。它表示该权限类必须是由signer_names所签名的,当然如果权限类是系统类则不受此限制。例如,假定有以下授权项: 
  grant {
    permission com.gameloft.Foo "foobar", signedBy "robin";
  }
如果com.gameloft.Foo类是为robin所签名,即可授予com.gameloft.Foo权限类型。 
权限项中出现的项目必须按指定顺序出现(permission,permission_class_name,"target_name","action"
和 signedBy "signer_names")。分号表示项终止。 
大小写对于标识符(permission、signedBy、codeBase 等)来说并不重要,但对于 permission_class_name 或作为值传递过来的字符串而言就很重要了。 
注意:在指定 java.io.FilePermission 时,"target_name" 是文件路径。在 Windows 系统上,无论何时在字符串中(而不是在 codeBase URL 中)直接指定文件路径,路径中都需要两个反斜杠来代表一个实际的反斜杠,如下例所示: 
  grant {
      permission java.io.FilePermission "C:\\users\\cathy\\foo.bat",
"read";
  };
原因在于:字符串是由符号处理器 (java.io.StreamTokenizer) 来处理的。符号处理器允许将“\”用作转义字符串(例如,“\n”表示换行),因此需要用两个反斜杠来表示一个反斜杠。符号处理器处理完以上文件路径字符串后,将把双反斜杠转换成单个反斜杠,其最终结果为: 
    "C:\users\cathy\foo.bat"

六、策略文件示例

示例1:
  grant signedBy "robin" {
    permission java.io.FilePermission "/tmp/*", "read,write";
  };
  表示赋予由 "robin" 签名的代码对/tmp中的所有文件授予读/写的访问权限
示例2: 
grant { permission java.util.PropertyPermission "java.vendor"; }; 
表示对所有用户赋予java.util.PropertyPermission权限。
示例3: 
  grant signedBy "sysadmin", codeBase "file:/home/sysadmin/*" {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
    permission java.security.SecurityPermission "Security.setProperty.*";
  };
表示对来自file:/home/sysadmin/*且被sysadmin签名的代码赋予调用 Security 类中的方法以添加或删除提供者或者设置 Security 属性的权限 
示例4: 
  grant signedBy "sysadmin" {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
  };
表示对由"sysadmin" 签名的代码赋予对java.security.SecurityPermission添加/删除提供者的权限,而不管 JAR 文件来源于何处。 
示例5: 
  grant codeBase "file:/home/sysadmin/-" {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
  };
表示本地文件系统“/home/sysadmin/”目录下任意位置的代码都赋予可以对java.security.SecurityPermission添加/删除提供者的权限。 而不管该代码是否被签名,以及由谁签名。 
示例6: 
  grant {
    permission java.security.SecurityPermission "Security.insertProvider.*";
    permission java.security.SecurityPermission "Security.removeProvider.*";
  };
表示对任何代码(不管来自于何处,是否已签名或由何人签名)都赋予可以对java.security.SecurityPermission可添加/删除提供者的权限。 

示例7:

grant { 
//对系统和用户目录“读”的权限
permission java.util.PropertyPermission "user.dir", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "java.class.path", "read";
permission java.util.PropertyPermission "user.name", "read";
//对线程和线程组的操作权限
permission java.lang.RuntimePermission "modifyThread";
permission java.lang.RuntimePermission "modifyThreadGroup";
//操作Socket端口的各种权限
permission java.net.SocketPermission "-", "listen";
permission java.net.SocketPermission "-", "accept";
permission java.net.SocketPermission "-", "connect";
permission java.net.SocketPermission "-", "read";
permission java.net.SocketPermission "-", "write";
//读写文件的权限
permission java.io.FilePermission "-", "read";
permission java.io.FilePermission "-", "write";
//退出系统的权限,例如System.exit(0)
permission java.lang.RuntimePermission "exitVM";
};

示例8:

grant principal javax.security.auth.x500.X500Principal "cn=Alice" {
      permission java.io.FilePermission "/home/Alice", "read, write";
 };
表示允许任何有特征 X500Principal, "cn=Alice" 的客户代码读写 "/home/Alice".
 示例9:
 grant codebase "http://www.games.com",
        signedBy "Duke",
        principal javax.security.auth.x500.X500Principal "cn=Alice" {
      permission java.io.FilePermission "/tmp/games", "read, write";
 };
This allows code downloaded from "www.games.com", signed by "Duke", and executed by "cn=Alice", permission to read and write into the "/tmp/games" directory.
示例10:
 keystore "http://foo.bar.com/blah/.keystore";
 
 grant principal "alice" {
      permission java.io.FilePermission "/tmp/games", "read, write";
 };
"alice" will be replaced by javax.security.auth.x500.X500Principal "cn=Alice"
assuming the X.509 certificate associated with the keystore alias, alice, has a subject distinguished name of "cn=Alice". This allows code executed by the X500Principal
"cn=Alice" permission to read and write into the "/tmp/games" directory.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息