jvm_7_安全管理器简介

0 Java安全模型组成部分:

a) 类装载器 ---> 可以自定义

b) class文件校验器

c)  安全管理器 ---> 可以自定义

安全管理器作用:  对于外部资源的访问启动控制作用, 默认安全管理器是没有安装

扫描二维码关注公众号,回复: 534522 查看本文章

通过代码简单看看安全管理器的作用:

protected ClassLoader(ClassLoader parent) {
	SecurityManager security = System.getSecurityManager();// 返回安全管理器对象java.lang.Security
	if (security != null) {//不为空时,安全管理器进行校验
	    security.checkCreateClassLoader();
	}
	this.parent = parent;
	initialized = true;
    }
  // 进入 校验方法
  public void checkCreateClassLoader() {
	checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
    }	
 // 进行进入后如下	
 public void checkPermission(Permission perm) {
	java.security.AccessController.checkPermission(perm);
    }	
// 继续进入如下

  public static void checkPermission(Permission perm)
		 throws AccessControlException 
    {
	//System.err.println("checkPermission "+perm);
	//Thread.currentThread().dumpStack();

	if (perm == null) {
	    throw new NullPointerException("permission can't be null");
	}

	AccessControlContext stack = getStackAccessControlContext();
	// if context is null, we had privileged system code on the stack. 如果当前的访问控制器上下文为空,在栈上的系统代码将得到特权
	if (stack == null) {
	    Debug debug = AccessControlContext.getDebug();
	    boolean dumpDebug = false;
	    if (debug != null) {
		dumpDebug = !Debug.isOn("codebase=");
		dumpDebug &= !Debug.isOn("permission=") ||
		    Debug.isOn("permission=" + perm.getClass().getCanonicalName());
	    }

	    if (dumpDebug && Debug.isOn("stack")) {
		Thread.currentThread().dumpStack();
	    }

	    if (dumpDebug && Debug.isOn("domain")) {
		debug.println("domain (context is null)");
	    }

	    if (dumpDebug) {
		debug.println("access allowed "+perm);
	    }
	    return;
	}

	AccessControlContext acc = stack.optimize();
	acc.checkPermission(perm);
    }	
	
进入acc.checkPermission(perm);方法如下: 看注释即可,
大意是遍历上下文中的保护域,一旦发现请求的权限不被允许,停止,抛出异常
/*
  * iterate through the ProtectionDomains in the context.
  * Stop at the first one that doesn't allow the
  * requested permission (throwing an exception).
  *
  */ /* if ctxt is null, all we had on the stack were system domains,
    or the first domain was a Privileged system domain. This
    is to make the common case for system code very fast */ if (context == null)
     return; for (int i=0; i< context.length; i++) {
     if (context[i] != null &&  !context[i].implies(perm)) {
  if (dumpDebug) {
      debug.println("access denied " + perm);
  }  if (Debug.isOn("failure") && debug != null) {
      // Want to make sure this is always displayed for failure,
      // but do not want to display again if already displayed
      // above.
      if (!dumpDebug) {
   debug.println("access denied " + perm);
      }
      Thread.currentThread().dumpStack();
      final ProtectionDomain pd = context[i];
      final Debug db = debug;
      AccessController.doPrivileged (new PrivilegedAction() {
   public Object run() {
       db.println("domain that failed "+pd);
       return null;
   }
      });
  }
  throw new AccessControlException("access denied "+perm, perm);
     }
 }

 通过上述代码一度跟踪流程,可知,安全管理器就是用来控制执行权限的。

默认下是没有开启的,通过如下代码来验证:

public class test2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(System.getSecurityManager());
	}

}

结果为null,


重新换个方式运行,在ecplise里右键--Run As--Run Configuration--Arguments,在VM arguments的栏目里输入
 -Djava.security.manager。在点击Run,结果为:
 java.lang.SecurityManager@de6ced
 这个时候默认的安全管理器就被安装上了。

猜你喜欢

转载自chengjianxiaoxue.iteye.com/blog/2150959