我正在浏览此API,摘自javadoc https://docs.oracle.com/javase/8/docs/technotes/guides/security/doprivileged.html#privileged_code
"当调用AccessController.checkPermission方法时 最近的调用者,决定是否允许的基本算法 或否认所请求的访问权限如下:
- 如果调用链中任何调用者的代码没有所请求的权限,则抛出AccessControlException
- 除非满足以下条件:授予其代码权限的呼叫者已被标记为特权,以及所有各方 随后被这个呼叫者(直接或间接)调用了 说许可。"
醇>
根据我对上述文档的理解,
让我们说frameA(有XYZ) - >调用 frameB(继承XYZ) 权限) - >调用 frameC(继承权限XYZ)。因为 SecurityManager是主线程的常用文件
因此,如果frameB想要执行需要权限ABC的代码 然后应该更改策略以授予该权限。但当 我将代码包装在AccessController.doPrivileged中,它不会抛出 SecurtyException。
所以我很困惑为什么它表现得像这样,这是因为 包装的代码自动给出"所有权限" ?如果是,请点2 以上是矛盾的,因为它说"一个代码为的调用者 授予上述许可已被标记为特权"
以下是我要测试的内容:
import java.security.*;
public class TestingDoPrivileged {
static SecurityPermission XYZ = new SecurityPermission("xyz");
static SecurityPermission ABC = new SecurityPermission("abc");
static SecurityPermission SET_POLICY = new SecurityPermission("setPolicy");
public static void main(String[] args) {
setDummySecurityManager();
frameA();
}
private static void frameA() {
//set the permission XYZ
setPolicy(XYZ,SET_POLICY);
//Here the code/resource frameA has access to XYZ permission
//Now call frameB which needs ABC permission for the code to execute.
frameB();
}
private static void frameB() {
//this will pass as this code has the permission XYZ because the policy is set in frameA with XYZ permission
System.getSecurityManager().checkPermission(XYZ);
try {
// this will fail as this code does not have permission for abc
System.getSecurityManager().checkPermission(ABC);
} catch (AccessControlException e) {
System.out.println("passed");
//pass
}
//As the caller of frameB which is frameA has the permission to XYZ only, the following code should fail,
// right? But it is passing.
AccessController.doPrivileged((PrivilegedAction) () -> {
frameC();
return null;
});
}
private static void frameC() {
System.getSecurityManager().checkPermission(ABC);
}
private static void setDummySecurityManager() {
setPolicy(SET_POLICY);
SecurityManager sm = new SecurityManager();
System.setSecurityManager(sm);
}
private static void setPolicy(Permission... perms) {
Policy.setPolicy(new Policy() {
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
PermissionCollection pc = new Permissions();
for (Permission pm : perms)
pc.add(pm);
return pc;
}
});
}
}
答案 0 :(得分:0)
Java 2安全模型适用于相关堆栈帧的权限的交集。如果任何相关框架(或两个参数doPrivileged
)没有权限,则访问控制上下文将不具有该权限。
在示例中,代码仅显示XYZ
和SET_POLICY
。在doPrivileged
内调用调用框架(类TestingDoPrivileged
)和lambda框架不具有ABC
权限,因此检查失败。
使用此类代码可能会发现,CodeSource
的权限仅查找一次。因此,试图改变它自己的权限的代码可能不会按预期运行。
运行代码,似乎永远不会调用getPermissions
。查看Policy
的来源会提醒我,ProtectionDomain
的{{1}}在设置时会获得完全权限。如果安全实现不受信任(通常在递归安全检查时堆栈溢出),则会导致问题。
使用策略文件会更好。那或者玩类加载器。