1,如果JVM开启了SecurityManager,ClassLoader在加载类的时候会调用Policy.getPermissions(CodeSource cs)获取代码权限集,并将代码来源和权限集封装到保护域;


wKioL1j7MdaDhuS9AAERVK5V9LQ042.png

2,在执行敏感操作(如IO)时,SecurityManager将执行权限检查:将调用敏感api的所有方法压入调用栈,

,由AccessController检查整个调用栈中每个方法的类的保护域(调用每个保护域的implies(Permission p)方法,仅当所有implies均返回true才允许执行敏感操作。

wKiom1j_SSyA6hEAAAKr2s38vPM243.png

3,如果通过doPrivileged()方法执行敏感操作,那么AccessController将检查栈顶到doPrivileged的调用者(somemethod方法的类,记作A)的保护域,而不管A的调用者是否具有权限。

 somemethod() {
     ...normal code here...
     String user = AccessController.doPrivileged(
         new PrivilegedAction<String>() {
         public String run() {
             敏感操作;
             }
         });
     ...normal code here...
 }