Java 2 安全性的访问控制异常
Java™ 2 安全行为由其安全策略指定。 安全策略是一个访问控制矩阵,它指定哪个系统资源某些代码库可访问以及谁必须标记它们。 Java 2 安全策略是声明性的,由java.security.AccessController.checkPermission方法。
以下示例描绘 java.security.AccessController.checkPermission 方法的算法。 要了解完整的算法,请参考安全性:学习资源一文中的 Java 2 安全检查权限算法。
当(i> 0){
if(调用者i的域没有权限)
抛出访问控制异常;
else if (调用者 i 被标记为特权)
返回;
i=i-1;
};
算法要求当执行 java.security.AccessController.checkPermission 方法或拒绝请求并创建 java.security.AccessControlException 异常时,调用堆栈上的所有类或调用者都具有许可权。 但是,如果将调用者标记为有特权,并且此类(调用者)被授予这些许可权,那么算法返回,并且不对整个调用堆栈进行遍历。 后续类(调用者)不需要被授予必需的许可权。
- 如果应用程序正在调用受 Java 2 安全保护的应用程序编程接口 (API),请向应用程序 Java 2 安全策略授予所需的权限。 如果应用程序没有直接调用 Java 2 安全保护的 API,则所需的权限是由第三方 API 访问 Java 2 安全保护的资源的副作用引起的。
- 如果将所需的许可权授予应用程序,那么与它需要的访问权相比,它会获得更多的访问权。 在这种情况下,访问 Java 2 安全保护资源的第三方代码很可能未被正确标记为特权。
调用堆栈示例
此调用堆栈示例表明应用程序代码在哪里使用第三方 API 实用程序库更新密码。 呈现以下示例,以描述此要点。 关于在哪里将代码标记为有特权的决定是特定于应用程序的,并且在每种情况下都是唯一的。 此决定需要深厚的域知识和安全性专门知识来作出正确的判断。 关于此主题有许多写得很好的出版物和书籍。 建议参阅这些资料,以了解更多详细信息。
可以使用 PasswordUtil 实用程序来更改用户的密码。 实用程序两次输入旧密码和新密码,以确保输入正确的密码。 如果旧密码匹配已存储在密码文件中的密码,那么存储新密码且更新该密码文件。 假设没有一个堆栈帧标记为有特权。 根据 java.security.AccessController.checkPermission 算法,除非调用堆栈上 的所有类都被授予对密码文件的写许可权,否则应用程序将失败。 客户机应用程序不具有任意直接写入密码文 件和更新密码文件的许可权。
但是,如果 PasswordUtil.updatePasswordFile 方法将访问密码文件的代码标记为有特权,那么只要授予了 PasswordUtil 类许可权,检查许可权算法不会从为所需的许可权调用 PasswordUtil.updatePasswordFile 方法的类检查所需的许可权。 客户机应用程序可以在不授予写入密码文件的许可权的情况下成功地更新密码。
将代码标记为有特权的能力是非常灵活和功效强大的。 如果不正确使用此能力,那么会危及整个系统安全性且会出现安全性漏洞。 请仔细地使用将代码标记为有特权的能力。
java.security.AccessControlException 异常的解决方案
- 为应用程序授予缺少的许可权。
- 在考虑问题和风险之后,将某些代码标记为有特权。