package com.shine.jarsigner; import com.shine.jarsigner.friend.Friend; import com.shine.jarsigner.stranger.Stranger; public class Example2c { public static void main(String[] args) { TextFileDisplayer tfd = new TextFileDisplayer("answer.txt"); Friend friend = new Friend(tfd,false); Stranger stranger = new Stranger(friend,true); stranger.doYourThing(); } }
package com.shine.jarsigner.friend; import com.shine.jarsigner.doer.Doer; import java.security.AccessController; import java.security.PrivilegedAction; public class Friend implements Doer { private Doer next; private boolean direct; public Friend(Doer next, boolean direct) { this.next = next; this.direct = direct; } public void doYourThing() { if (this.direct) this.next.doYourThing(); else AccessController.doPrivileged( new PrivilegedAction() { public Object run() { Friend.this.next.doYourThing(); return null; } }); } }
package com.shine.jarsigner.stranger; import com.shine.jarsigner.doer.Doer; import java.security.AccessController; import java.security.PrivilegedAction; public class Stranger implements Doer { private Doer next; private boolean direct; public Stranger(Doer next, boolean direct) { this.next = next; this.direct = direct; } public void doYourThing() { if (this.direct) this.next.doYourThing(); else AccessController.doPrivileged( new PrivilegedAction() { public Object run() { Stranger.this.next.doYourThing(); return null; } }); } }
Stranger和Friend 都是具有JVM安全控制的jar包,且使用jarsigner进行了证书签名
且Stranger具有访问当前项目底下quesion.txt权限,而 Friend具有访问 quesion.txt和answer.txt文件权限
权利文件:policyfile.txt
keystore "ijvmkeys";
grant signedBy "friend"{
permission java.io.FilePermission "question.txt","read";
permission java.io.FilePermission "answer.txt","read";
};
grant signedBy "stranger"{
permission java.io.FilePermission "question.txt","read";
};
grant codeBase "Z:/云系统/test/workspace/test4/src/com/shine/jarsigner/*"{
permission java.io.FilePermission "question.txt","read";
permission java.io.FilePermission "answer.txt","read";
}
1、Eclipse Run Example2c,且设置JVM执行参数 -Djava.security.manager -Djava.security.policy=policyfile.txt
2、此时java栈:
由此可以看出jvm 栈 类加载顺序,调用者先入栈,上图是main方法开始调用的,然后是Stranger的doYourThing(),再调用Firend的doYourThing()
接着Firend调用了AccessController.doPrivlieged(),让JVM忽视调用者的权限(也就是说Stranger没有读取answer.txt文件的权限,也没关系),必须执行当前权限的职责(Friend权限,此处Friend有读取answer.txt文件的权限)。JVM的访问权限检查是从栈顶开始,从12步开始,到第3步结束,忽略调用者权限第2,1步。