java 安全模型
组成
安全管理器
SecurityManage
访问控制器
AccessController
类加载器
ClassLoader
基于域的安全模型
代码源
CodeSource类
生命从哪里加载类 指定类加载器
权限
Permission 是 AccessController 类处理的基本实体
一个实例代表一个具体的权限
public final class FilePermission extends Permission implements Serializable {
//权限 数字 1-读 2-写 3-读写 4-删除
private transient int mask;
//权限 字符串 read,write,delete
private String actions;
//文件或是文件夹路径
private transient String cpath;
//权限名 路径
private String name;
//是否是目录
private transient boolean directory;
//是否递归目录
private transient boolean recursive;
FilePermission(String path, int mask) {
super(path);
init(mask);
}
//校验权限 检验当前permission的mask是否包含被校验对象的mask
public boolean implies(Permission p) {
if (!(p instanceof FilePermission))
return false;
FilePermission that = (FilePermission) p;
// we get the effective mask. i.e., the "and" of this and that.
// They must be equal to that.mask for implies to return true.
return ((this.mask & that.mask) == that.mask) && impliesIgnoreMask(that);
}
//校验Permission对象的路径是否包含或相同
boolean impliesIgnoreMask(FilePermission that) {
if (this.directory) {
if (this.recursive) {
//如果目录可递归 那么当前对象的路径应该比that的路径长或相等 包含关系
// make sure that.path is longer then path so
// something like /foo/- does not imply /foo
if (that.directory) {
return (that.cpath.length() >= this.cpath.length()) &&
that.cpath.startsWith(this.cpath);
} else {
return ((that.cpath.length() > this.cpath.length()) &&
that.cpath.startsWith(this.cpath));
}
} else {
//如果当前目录不可递归 目录相等关系
if (that.directory) {
// if the permission passed in is a directory
// specification, make sure that a non-recursive
// permission (i.e., this object) can't imply a recursive
// permission.
if (that.recursive)
return false;
else
return (this.cpath.equals(that.cpath));
} else {
int last = that.cpath.lastIndexOf(File.separatorChar);
if (last == -1)
return false;
else {
// this.cpath.equals(that.cpath.substring(0, last+1));
// Use regionMatches to avoid creating new string
//提取that文件的路径进行相等判断
return (this.cpath.length() == (last + 1)) &&
this.cpath.regionMatches(0, that.cpath, 0, last+1);
}
}
}
} else if (that.directory) {
//一个是目录一个是文件
// if this is NOT recursive/wildcarded,
// do not let it imply a recursive/wildcarded permission
return false;
} else {
//两个都是文件 大小写敏感
return (this.cpath.equals(that.cpath));
}
}
}
策略
Policy 类
策略是一组权限的总称 用于确定权限应该用于哪些代码源
代码源标识类的来源
权限声明了具体的限制
private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping;
Collection<Permission> getPermissions(CodeSource)
Collection<Permission> getPermissions(ProtectionDomain)
保护域
ProtectionDomain
代码源和相应权限的一个组合
JVM的每一个类都一定属于且仅仅属于1个保护域,由ClassLoader在定义class的时候决定
内置ClassLoader没有指定保护域,属于系统保护域
权限控制有2种
正常的权限访问
特权访问
AccessController.doPrivilege();