jvm_10_策略和保护域

 

 

0 策略文件续:

 

看如下策略文件myPolicy.txt

keystore "ijvmkeys";
grant signedby "friend" {   
    permission java.io.FilePermission "d:/testPolicy.txt", "read,write";   
}; 

grant signedby "stranger" {   
    permission java.io.FilePermission "d:/testPolicy.txt", "read,write";   
}; 
 

grant codeBase "file:D:/workspace/TestPolicy/bin/*" {   
    permission java.io.FilePermission "d:/testPolicy.txt", "read,write";   
}; 

 

第一行:keystore "ijvmkeys",这一行的意思,密钥对存放在当前目录一个叫ijvmkeys的文件里(记得笔记八做过的jar包签名实验吗)

第二行:grant signedby "friend",grant是授权的意思,这一行的意思是,给一个被“friend”的密钥对签名的文件授权

第三行:permission java.io.FilePermission "d:/testPolicy.txt", "read,write";这行的意思是对于d:/testPolicy.txt赋予读写的权限

倒数第三行:grant codeBase "file:D:/workspace/TestPolicy/bin/*" ,对D:/workspace/TestPolicy/bin/*下的所有文件赋予权限。

 

策略文件总结:

a) 策略文件可以给一系列被签名的代码库(“friend”,‘stranger“都是代码库)授权,

     也可以给一个代码来源(一个具体的路径或者说url就是一个代码来源)授权。

b) 策略文件不仅可以存储在文件中(后缀名是什么不重要),还可以存放在数据库里。

 

 

疑问: 一个应用程序对应一个策略单例,一个策略单例对应一个策略文件,它到底怎么对应的???

 

 

 

 

1 保护域:

a) 类装载器将class文件load内存的时候会将它放置到一个保护域中,

b) 每一个装入虚拟机的类型都会属于且仅属于一个保护域,

c) 保护域定义了授予代码的执行权限,

d) 一个保护域对应策略文件中的一个或多个Grant字句

 

下面看类加载器加载类文件到指定保护域的流程:

 

类装载器知道它装载的所有类或接口的代码库和签名者---> 它利用这些信息来创建一个CodeSource对象

--->将这个CodeSource对象传递个当前Policy对象的getPermissions()方法

--->得到这个抽象类java.security.PermissionCollection的子类实例

--->实例化对象ProtectDomain ---> 传递给defineClass()方法

 


jvm_10_策略和保护域_第1张图片
 

 

 

2 上文涉及的知识点详解:

 

2.1) codeSource:代码源

 

签名的版本,签名者,还有被签名的类名,以及这个类的hash摘要

 

classLoader通过读取class文件,jar包得知谁为这个类签过名(可以有多个签名者)

后封装成一个签名者数组赋给codeSource对象的signers成员,

通过这个类的来源(可能来自一个本地的url或者一个网络的ur)赋给codeSource的location成员,

这个类的公钥证书赋给codeSource的certs成员(常一个jar是能够被多个团体或者机构担保的,也就是我们说的认证)

源码如下:

public class CodeSource implements java.io.Serializable {

    private static final long serialVersionUID = 4977541819976013951L;

    /**
     * The code location.
     *
     * @serial
     */
    private URL location;//本地代码库
    /*
     * The code signers.
     */
    private transient CodeSigner[] signers = null;//签名者

    /*
     * The code signers. Certificate chains are concatenated.
     */
    private transient java.security.cert.Certificate certs[] = null;//证书

 

2.2) Policy:策略, 就是用来读取策略文件的一个单例对象,通过传入的CodeSource对象

(由于codeSource对象里包含了签名者和代码来源),所以他通过读取grant段,

取出一个个的Perssiom然后返回一个PerssiomCollection,这个类有一个很重要的成员变量,

    // Cache mapping  ProtectionDomain to PermissionCollection
    private WeakHashMap pdMapping;

    private static void initPolicy (final Policy p) {
              ......
 
     	if (policyDomain.getCodeSource() != null) {
	      .......
	    synchronized (p.pdMapping) {
		// cache of pd to permissions
		p.pdMapping.put(policyDomain, policyPerms);
	    }
	}
	return;
    }

 

pdMapping就是把保护域对象当做key将权限集合当做value存在在了这个map里,

所以我们说一个保护域对应多个策略文件的grant子句的permission。

 

 

2.3) ProtectionDomain:保护域,他就是用来容纳class文件,还有perssiom,codeSource的一个对象,

代码如下:

public class ProtectionDomain {

    /* CodeSource */
    private CodeSource codesource ;//代码源

    /* ClassLoader the protection domain was consed from */
    private ClassLoader classloader;//类装载器
    /* Principals running-as within this protection domain */
    private Principal[] principals;

    /* the rights this protection domain is granted */
    private PermissionCollection permissions;//权限集合

 

 

2.4) Permission:权限,它的结构也很简单,权限名和动作,

java.io.FilePermission是一个权限名

而动作则是read和write,

 

2.5) 总计关系图如下:


jvm_10_策略和保护域_第2张图片
 

 

3 总结:

 

类装载器装载类时--->调用安全管理器--->通过判定策略决定我们是否加载这个类/执行某操作

---> 生成ProtectionDomain保护域后,class字节码在内存中被放在了这个保护域中。

 

 

 

你可能感兴趣的:(jvm)