七、策略文件中的属性扩展
策略文件和安全属性文件中可以进行属性扩展。 属性扩展类似于扩展 shell 中的变量。
也就是说,当类似
${some.property}
的字符串出现在策略文件或安全属性文件中时,它将被扩展为
JAVA系统属性
的值。
例如:
permission java.io.FilePermission "
${user.home}
", "read";
将把 "
${user.home}
" 扩展为使用 "
user.home
" 系统属性的值。如果该属性的值是 "/home/cathy",则以上示例等价于:
permission java.io.FilePermission "/home/cathy", "read";
可以在JAVA代码总
通过System.getProperty()方法取得
JAVA系统属性
的值。关于
JAVA系统属性
的更多内容请参考《
读取JAVA系统属性
》
7.1、通用文件分割符
可以了为了能在与平台无关的策略文件中使用,也可采用特殊记号 "
${/}
"表示
文件分割符
。该记号是 "${file.separator}" 的简化表示。这种方式允许使用下列字符串:
permission java.io.FilePermission "${user.home}${/}*", "read";
如果 "user.home" 属性的值是 /home/cathy,而且是在 Solaris 系统上,则以上字符串将转换为:
permission java.io.FilePermission "/home/cathy/*", "read";
如果 "user.home" 值是 C:\users\cathy,而且是在 Windows 系统上,则以上字符串将转换为:
permission java.io.FilePermission "C:\users\cathy\*", "read";
同样,作为一种特例,如果在codebase中使用扩展属性,例如
grant codeBase "file:${java.home}/lib/ext/"
则任何文件分隔符都将自动转换为“/”。这样,在 Windows 系统上,以上字符串将转换为:
grant codeBase "file:C:/jdk1.2/lib/ext/"
即使 "java.home" 被设置为 C:\jdk1.2。因此,用户就不必也不应该在 codeBase 字符串中使用 ${/}。
7.2、什么地方可使用属性扩展
策略文件中允许使用双引号字符串的地方都可进行属性扩展。
其中包括 "
signer_names
"、"
URL
"、"
target_name
" 和 "
action
" 域。
是否允许属性扩展
由
安全属性文件中的“policy.expandProperties”属性控制
。如果该属性为
真
(缺省值),则
允许扩展
。
请注意:不能使用嵌套属性;嵌套属性将无效。 例如,
"${user.${foo}}"
是无效的,即使将“foo”属性设置为“home”。原因在于属性解析程序不能识别嵌套属性;解析程序只是简单地搜索第一个“${”,然后继续搜索直到找到第一个“}”为止,同时试图将搜索结果(这里是 "${user.$foo}")解释为属性。如果没有这种属性,则解析程序就会发生解释失败。
如果在 grant 项、permission 项或 keystore 项中无法扩展某个属性,则该项将被忽略。
例如,如果在没有定义系统属性“foo”的情况下使用语句:
grant codeBase "${foo}" {
permission ...;
permission ...;
};
则该 grant 项中的所有权限都将被忽略。
如果使用语句:
grant {
permission Foo "${foo}";
permission Bar;
};
则将仅忽略“permission Foo...”项。
最后,如果使用语句:
keystore "${foo}";
则将忽略 keystore 项。
7.2、Windows系统上的文件分割符
如上所述,在 Windows 系统上,当直接在字符串中(而不是在 codeBase URL 中)指定文件路径时,用户需要用两个反斜杠来代表文件路径中一个实际的反斜杠,如下例所示:
grant {
permission java.io.FilePermission "C:\\users\\cathy\\foo.bat", "read";
};
字符串是由符号处理器 (java.io.StreamTokenizer) 来处理的,它允许将“\”用作转义字符串(例如,“\n”表示换行),因此需要用两个反斜杠来表示一个反斜杠。符号处理器处理完以上文件路径字符串后,将把双反斜杠转换成单个反斜杠,其最终结果为:
"C:\users\cathy\foo.bat"
符号处理器处理完字符串后,即进行字符串中的属性扩展。因此,如果使用字符串:
"${user.home}\\foo.bat"
则符号处理器首先处理字符串,即将双反斜杠转换成单个反斜杠,其结果为:
"${user.home}\foo.bat"
随即扩展 ${user.home} 属性,假设
user.home是C:\Documents and Settings\hubin,则其最终结果为:
"
C:\Documents and Settings\hubin
\foo.bat"
当然,为实现与平台无关,最好在开始指定字符串时不要显式带上斜杠,即可以用
${/}
来代替,如下例所示:
"${user.home}${/}foo.bat"
7.3、泛化形式的扩展
Policy文件中也支持扩展的泛化形式。 permission 名称中可能有以下形式的字符串:
${{protocol:protocol_data}}
如果这样的字符串出现在permission名字中,protocol中的值决定了该发生扩展的精确类型,而 protocol_data 被用来帮助实现扩展。protocol_data 可能是空的,那样就可简单的写为以下形式:
${{protocol}}
默认policy文件的实现中支持两种protocols:
7.3.1 ${{self}}
The protocol, self,指明一个条目字符串中以principal名值对发生的替换。,精确的替换依赖于permissions 跟随的grant子句的内容。
如果grant子句不含任何principal信息, permission 就会被忽略 (包含${{self}} 于target names 的permissions 只有在基于principal的grant子句上下文中才有意义。如下的BarPermission 将总是被忽略:
grant codebase "www.foo.com", signedby "duke" {
permission BarPermission "... ${{self}} ...";
};
如果grant有principal,那么, ${{self}} 将被同样的principal 信息替换,如下例${{self}} 将被替换为:
javax.security.auth.x500.X500Principal "cn=Duke"
。
grant principal javax.security.auth.x500.X500Principal "cn=Duke" {
permission BarPermission "... ${{self}} ...";
};
以逗号分割的principal列表,也将以同样的方式被复制。
7.3.2 、${{alias:alias_name}}
The KeyStore used is the one specified in the KeyStore entry. alias_name 代表了 KeyStore中的一个别名.如:
keystore "http://foo.bar.com/blah/.keystore";
grant codebase "www.foo.com" {
permission BarPermission "... ${{alias:duke}} ...";
};
上例中 X.509 证书可以从 foo.bar.com/blah/.keystore.获得。 假设duke的证书指明了"o=dukeOrg, cn=duke" 作为subject 的区别名称,则${{alias:duke}} 被一下字符串替换javax.security.auth.x500.X500Principal "o=dukeOrg, cn=duke".
发生以下错误时,permission将被忽略:
* 没有 keystore条目
* 没有提供 alias_name
* alias_name的证书不能获得。can not be retrieved
* 证书不是x.509的