保护敏感操作
public void somemethod() {
permission permission =
new java.net.socketpermission("localhost:8080", "connect");
accesscontroller.checkpermission(permission);
// sensitive code starts here
socket s = new socket("localhost", 8080);
}
在这个示例中,我们看到 accesscontroller 检查应用程序的当前策略实现。如果策略文件中定义的任何许可权暗示了被请求的许可权,该方法将只简单地返回;否则抛出一个 accesscontrolexception 异常。在这个示例中,检查实际上是多余的,因为缺省套接字实现的构造函数也执行相同的检查。
在下一部分,我们将更仔细地看一下 accesscontroller 如何与 java.security.policy 实现共同合作安全地处理应用程序请求。
运行中的 accesscontroller
accesscontroller 类典型的 checkpermission(permission p) 方法调用可能会导致下面的一系列操作:
accesscontroller 调用 java.security.policy 类实现的 getpermissions(codesource codesource) 方法。
getpermissions(codesource codesource) 方法返回一个 permissioncollection 类实例,这个类实例代表一个相同类型许可权的集合。
accesscontroller 调用 permissioncollection 类的 implies(permission p) 方法。
接下来,permissioncollection 调用集合中包含的单个 permission 对象的 implies(permission p) 方法。如果集合中的当前许可权对象暗示指定的许可权,则这些方法返回 true,否则返回 false。[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
现在,让我们更详细地看一下这个访问控制序列中的重要元素。
permissioncollection 类
大多数许可权类类型都有一个相应的 permissioncollection 类。这样一个集合的实例可以通过调用 permission 子类实现定义的 newpermissioncollection() 方法来创建。java.security.policy 类实现的 getpermissions() 方法也可以返回 permissions 类实例 — permissioncollection 的一个子类。这个类代表由 permissioncollection 组织的不同类型许可权对象的一个集合。permissions 类的 implies(permission p) 方法可以调用单个 permissioncollection 类的 implies(permission p) 方法。
codesource 和 protectiondomain 类
许可权组合与 codesource(被用于验证签码(signed code)的代码位置和证书)被封装在 protectiondomain 类中。有相同许可权和相同 codesource 的类实例被放在相同的域中。带有相同许可权,但不同 codesource 的类被放在不同的域中。一个类只可属于一个 protectiondomain。要为对象获取 protectiondomain,请使用 java.lang.class 类中定义的 getprotectiondomain() 方法。
许可权
赋予 codesource 许可权并不一定意味着允许所暗示的操作。要使操作成功完成,调用栈中的每个类必须有必需的许可权。换句话说,如果您将 java.io.filepermission 赋给类 b,而类 b 是由类 a 来调用,那么类 a 必须也有相同的许可权或者暗示 java.io.filepermission 的许可权。
在另一方面,调用类可能需要临时许可权来完成另一个拥有那些许可权的类中的操作。例如,当从另一个位置加载的类访问本地文件系统时,我们可能不信任它。但是,本地加载的类被授予对某个目录的读许可权。这些类可以实现 privilegedaction 接口来给予调用类许可权以便完成指定的操作。调用栈的检查在遇到 privilegedaction 实例时停止,有效地将执行指定操作所必需的许可权授予所有的后继类调用。
使用 jaas
顾名思义,jaas 由两个主要组件组成:认证和授权。我们主要关注扩展 jaas 的授权组件,但开始我们先简要概述一下 jaas 认证,紧接着看一下一个简单的 jaas 授权操作。
jaas 中的用户认证
jaas 通过添加基于 subject 的策略加强了 java 2 中定义的访问控制安全性模型。许可权的授予不仅基于 codesource,还基于执行代码的用户。显然,要使这个模型生效,每个用户都必须经过认证。
jaas 的认证机制建立在一组可插登录模块的基础上。jaas 分发版包含几个 loginmodule 实现。loginmodules 可以用于提示用户输入用户标识和密码。logincontext 类使用一个配置文件来确定使用哪个 loginmodule 对用户进行认证。这个配置可以通过系统属性 java.security.auth.login.config 指定。一个示例配置是:
java -djava.security.auth.login.config=login.conf
下面是一个登录配置文件的样子:
example {
com.ibm.resource.security.auth.loginmoduleexample required
debug=true userfile="users.xml" groupfile="groups.xml";
};
认识您的主体
subject 类被用于封装一个被认证实体(比如用户)的凭证。一个 subject 可能拥有一个被称为主体(principal)的身份分组。例如,如果 subject 是一个用户,用户的名字和相关的社会保险号可能是 subject 的某些身份或主体。主体是与身份名关联在一起的。
principal 实现类及其名称都是在 jaas 策略文件中指定的。缺省的 jaas 实现使用的策略文件与 java 2 实现的策略文件相似 — 除了每个授权语句必须与至少一个主体关联在一起。javax.security.auth.policy 抽象类被用于表示 jaas 安全性策略。它的缺省实现由 com.sun.security.auth.policyfile 提供,在 com.sun.security.auth.policyfile 中策略定义在一个文件中。清单 3 是 jaas 策略文件的一个示例:
|
|