Java虚拟机体系结构 - 访问策略1

策略:

Java安全体系结构的优点之一就是:代码可以被授予只对它需要的资源进行访问的有限权限。即使一些恶意的或者有漏洞的代码得到了认证,它也会很少有机会进行破坏。为了实现这种细粒度的访问,Java访问控制机制必须能够确认应该给代码授予什么样的权限;因此,在Java版本1.2虚拟机中,将每个代码段(class文件)和一个代码来源(CodeSource - 代码来源包含了一个java.net.URL对象, 主要 用来说明代码从哪里来,以及 如果 该代码被签名了的话 ,是哪个证书机构为这个签名做担保)  关联 在版本1.2的安全模型中,系统访问权限是授予代码来源的,因此,当代码段请求访问一个特定的系统资源时,只有与这个代码段相关联的代码来源定义了相应的权限,Java虚拟机才会把请求的资源授予该代码段。在版本1.2中,代码来源用来描述运行时代码的属性,它所包含的java.net.URL对象用来表示代码库和代表了签名者的零个或多个证书对象的数组(因为一段代码可以被多个证书机构所担保)。证书对象是抽象类java.security.cert.Certificate的子类实例,一个Certificate对象表示了从一个主体(发布密钥对的人)到一个公钥的绑定,以及为这个绑定做担保的证书机构。(具体参见Jar包的签名与认证
        所有的访问控制体系结构和安全管理工具都只能对证书起作用,而不能对“赤裸”的公钥起作用;如果附近没有证书机构,可以使用私钥对公钥签名,生成一个自签名的证书。
        对于整个Java应用,访问控制策略是由抽象类java.security.Policy的一个子类的实例所表示的(有且仅有)。通过把一个新的Policy对象的引用传递给Policy.setPolicy( ) 方法来设置当前的Policy对象,类装载器利用这个Policy对象来决件 定它所装载的.class文 应该赋予什么样的权限。在Policy对象中,每个CodeSource是和一个或多个Permission对象相关联的,该Permission对象是抽象类java.security.Permission的一个子类的实例,用来表示代码的权限;该实例对象拥有三个属性:类型、名字和可选操作(例如:用类名java.io.FilePermission指定权限的类型;权限的名字被封装在一个Permission对象内,用来说明对可访问的资源,如某个文件;可选操作是对该资源的可操作的权限,如文件的读写) 。和每一个CodeSource相关联的一个或多个Permission对象被封装在java.security.PermissionCollection的一个子类实例中,类装载器可以调用Policy.getPolicy( )来获得一个当前有效的Policy对象的引用,然后可以给Policy对象的getPermission()方法传递一个CodeSource对象来获得与当前CodeSource对象关联的PermissionCollection对象。类装载器可以通过使用这个从Policy对象中得到的PermissionCollection对象来授予代码相应的权限。

策略文件:

java.security.Policy是一个抽象类,具体的策略实现由子类来完成。在java 1.2版本中,具体的子类通过从一个ASCII策略文件中读取由上下文无关文法描述的安全策略。例如下列的策略文件:
        keystore "ijvmkeys"//keystore语句说明,指向存储在名为"ijvmkeys"的文件中的证书
        grant signedBy "friend" {//grant 子句,将一些权限授予一个代码来源
permission java.io.FilePermission "question.txt","read";//对应Permission类的三个属性
permission java.io.FilePermission “answer.txt","read";
}
...

保护域:

当类装载器将类型装入Java虚拟机时,每一个类型被指派(有且仅有)一个保护域。保护域定义了授予一段代码的所有权限(一个保护域对应策略文件的一个或多个grant子句)。
类装载器知道它装载的所有类和接口的代码库和签名者(由签名的jar包得到),类装载器利用这些信息来创建一个CodeSource对象,并将这个CodeResource对象传递给当前Policy对象的getPermission( )方法,用来得到抽象类PermissionCollection子类的实例,然后利用CodeResource和该PermissionCollection对象实例化一个ProtectDomain对象。通过将一个ProtectDomain对象传递给ClassLoader类的defineClass( )实例方法,来将这段代码放到一个保护域中。如图1-1描述了保护域、代码来源以及权限之间的关系:


图1-1 保护域、代码来源以及权限

访问控制器:

类java.security.AccessController提供了一个默认的安全策略执行机制,它使用栈检查来决定潜在不安全的操作是否被允许。该访问控制器不能被实例化,他不是一个对象,而是集合在该类中的多个静态方法。AccessController最核心的方法是checkPermission( )静态方法,这个方法决定一个特定的操作能否被允许。该方法将执行Permission对象的引用作为其唯一参数,并返回void,如果被检查的操作被允许,它将简单返回,如果操作被禁止,该方法将抛出一个AccessControlException异常。
AccessController的checkPermission( )实现的基本算法决定了调用栈中的每个帧是否有权限执行潜在不安全的操作。每个栈帧代表了由当前线程调用的某个方法,方法是在某个类中定义的,每个类又属于某个保护域,每个保护域又包含一些权限,因此,每个栈帧间接地和一些权限相关。checkPermission( )方法自顶向下检查栈,只要它遇到一个没有权限的栈帧,它将抛出一个AccessControlException异常;如果checkPermission( )方法到达栈的底部也没有遇到操作不被允许的栈帧,checkPermission()方法将简单返回。
implies( ) 方法被AccessController用来确定一个线程是否有进行某些操作的权限。例如,通过 调用 AccessController的checkPermission(FilePermission permission )方法来检查当前线程是否有权读取某文件时,AccessController将会调用与该栈帧相关联的ProtectionDomain对象的implies( ) 来检查这个线程是否拥有permission访问该文件的权限。而ProtectionDomain对象的implies( )方法会调用ProtectionDomain封装PermissionCollection的implies( )方法;同样,该PermissionCollection对象的implies( )方法会调用它所包含的Permission对象上的implies() 方法,一旦某个Permission对象的implies()方法返回true,那么与之关联的ProtectionDomain的implies()方法也会返回true,当所有的Permission对象的implies()方法都返回false时,ProtectionDomain也将返回false。例如下列代码:
import java.security.Permission;
import java.io.FilePermission;
import java.io.File;
class Example1 {
public static void main( String args []) {
char sep = File.separatorChar;
Permission file = new FilePermission(sep + "tmp" + sep + "f", "read");
Permission star = new FilePermission(sep + "tmp" + sep + "*", "read");

boolean starImpliesFile = star.implies(file);//star拥有tmp目录下所有文件的读权限
boolean fileImpliesStar = file.implies(star);//file只拥有tmp目录下对f文件的读权限

System.out.println("star implies file = " + starImpliesFile);
System.out.println("File implies star = " + fileImpliesStar);
}
}


应用程序输出:
star implies file = true
file implies star = false
因为star拥有tmp目录下所有文件的读权限(当然也包括f文件的读权限),所以star.implies(file)返回true;反之,file只拥有对f文件的读权限而不包括tmp目录下的所有文件的读权限,因此file.implies(star)返回false。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值