Java 访问控制机制的原理是:在某些策略配置文件中预定义好某些代码对某些资源具有某些操作权限,当某些代码以某个权限访问某个资源的时候,如果对该资源预指定的权限中没有该权限,则禁止访问,否则可以访问。
上面一段话读起来比较晦涩,下面先以数据库用户和数据表为例来说明。
指定某些代码对某些资源具有某些操作权限
某些代码:用户 Admin, X
某些资源:数据库表 User
操作权限:用户 Admin(某些代码)对 User 表(某些资源) 具有 CRUD 权限
用户 X(某些代码)对 User 表(某些资源) 具有 R 权限
某些代码以某个权限访问某个资源
用户 X(某些代码)查询(某个权限) User 表(某些资源),因为预定义中用户 X 对 User 表是有查询权限的,所以检查通过
用户 X(某些代码)删除(某个权限) User 表(某些资源) 中某条数据,因为预定义中用户 X 对 User 表只有查询权限,没有删除权限的,所以检查不通过
在 Java 中,道理也是一样的,只是 Java 中某个类相当于上面的某个用户,如 ClassA 相当于用户 Admin, ClassB 相当于用户 X。 但是在 Java 中情况稍微复杂一点,比如 ClassB 可以调用 ClassA 的方法,那么这时候,权限将如何检查呢?还是以例子来说明。
指定某些代码对某些资源具有某些操作权限
某些代码:用户 ClassA, ClassB
某些资源:某个配置文件 x.properties
操作权限:ClassA(某些代码)对 x.properties(某些资源) 具有读写权限
ClassB(某些代码)对 x.properties(某些资源) 具有读权限
某些代码以某个权限访问某个资源
ClassA(某些代码)读或写(某个权限) 配置文件x.properties(某些资源),因为预定义中ClassA 对 x.properties是有读和写权限的,所以检查通过
ClassB(某些代码)读(某个权限) 配置文件x.properties(某些资源),因为预定义中ClassB对 x.properties是有读权限的,所以检查通过
ClassB(某些代码)写(某个权限) 配置文件x.properties(某些资源),因为预定义中ClassB对 x.properties是没有写权限的,所以检查不通过
Class B 调用 ClassA 的写 x.properties 文件方法,是什么检查过程呢?
在 Java 中,不管有几个类的反复调用,最终都是以某个权限操作某个资源,如这里是 Class B 调用 ClassA,其最终操作权限是以写的权限去操作 x.properties 文件。那么 Java 就会对反复调用过程中的所有类进行检查,看它们对 x.properties 文件是否有写权限,如果都有则通过,只要任何一个类没有该权限,则不通过。
其中检查的过程与调用过程是互为逆向的。如在上例中,ClassB 调用 ClassA 的去写 x.properties 文件,那么 JVM 就会先检查 ClassA 对 x.properties 文件是否有写权限,因为预定义中有,所以 ClassA 通过。接下来检查 ClassB,因为预定义中,ClassB对 x.properties 文件没有写 权限,所以检查不通过,本次操作失败。
在 Java 访问控制机制中,主要有以下几个类:
SecurityManager
AccessController
AccessControlContext
ProtectionDomain
PermissionCollection
Permission
Policy
SecurityManager/ AccessController
访问控制的入口类。在 Java 中,访问控制默认是关闭的。
AccessControlContext
类的调用过程上下文。它以栈的形式保存类的调用过程,如在上面例子中,ClassB 调用 ClassA,那么 AccessControlContext 的栈底是 ClassB,栈顶是 ClassA,如果 ClassA 再调用 ClassC,那么 ClassC 在压入栈,栈顶变成了 ClassC
ProtectionDomain
这是一个关键的类。它定义了“某些代码对某些资源具有某些操作权限”,亦即那个目录下的代码对那些资源有哪些操作权限。它有三个属性:
某些代码
一般是指某个目录下的所有代码,如 “JRE_HOEM/lib/ext”在 Java 中表示为 CodeBase
某些资源
比如 conf 目录下的文件,在 Java 中表现为某个文件(夹)路径 BasePath
某些权限
是指某些代码对对某些资源操作权限的集合,比如读权限、写权限,在 Java 中表现为 PermissionCollection 类。
PermissionCollection
权限的集合类。如文件读权限、文件写权限的集合:
FilePermission(file,SecurityConstants.FILE_WRITE_ACTION)
FilePermission(file,SecurityConstants.FILE_READ_ACTION)
Permission
某个具体的权限。如文件读权限 FilePermission(file,SecurityConstants.FILE_WRITE_ACTION)
Policy
“指定某些代码对某些资源具有某些操作权限”的策略定义在策略文件中,Policy 负责从配置文件中读取这些策略,并根据策略文件构建 ProtectionDomain。JVM 中只有一个 Policy 对象。
“某些代码对某些资源具有某些操作权限”建立过程
在 Java 中,每个类都有一个 ProtectionDomain 的一个引用,因为每个类都属于某个特定的目录下,这样就可以知道某个类对某些资源有哪些操作权限了。下面看每个类与 ProtectionDomain 建立关系的过程:
当 ClassLoader 去加载一个 class 的时候,它会把这个类及授给这个类的权限集封装到“java.security.ProtectionDomain”中,其中这些权限是通过 ClassLoader并根据策略文件进行分配的。
1) 找到类字节码的加载 URL
2) 如果这个类是从包 java.* 中加载的,那就把该类与内在的 System ProtectionDomain 关联,其中 System ProtectionDomain 是具有全部权限(AllPermission)的。如果该类不是从包 java.* 中加载的,则继续
3) 如果该类要关联的 ProtectionDomain 以及存在,则直接添加它们之间引用关系即可,否则继续
4) 创建一个 CodeSource 对象,里面封装了类字节码的加载路径
5) 创建一个 PermissionCollection 对象,并把策略文件中赋给 CodeSource 的权限封装到该 PC 对象中
6) 创建一个 ProtectionDomain,里面封装了 CodeSource 和 PermissionCollection 对象,即那些代码对那些资源有那些操作权限:ProtectionDomain = new ProtectionDomain(CodeSource,PermissionCollection)
7) 把刚加载的 class 类与当前的 ProtectionDomain 关联
各个类之间引用调用关系这里不阐述,下面继续看例子:
现在假设有如下代码:${user.dir}/testA/ClassA ${user.dir}/testB/ClassB
有如下资源:${user.dir}/conf/x.properties
加入在 Java 策略文件中添加如下策略:
grant codeBase "file:${user.dir}/testA/*" {
permission java.io.FilePermission "${user.dir}/conf *", "read";
permission java.io.FilePermission "${user.dir}/conf *", "write";
};
grant codeBase "file:${user.dir}/testB/*" {
permission java.io.FilePermission "${user.dir}/conf *", "read";
};
上面有提到,在Java 中每个 Class都保存有 ProtectionDomain的引用,这里 ClassA 和 ClassB 的 ProtectionDomain 模型如下:
下面假设 ClassB 调用 ClassA 的去写 x.poperties 文件,那么 AccessControlContext 和 PermissionCollection 对应模型是这样的:
当 AccessController.checkPermission 开始检查权限时,它知道要本次要检查的权限是 FilePermission(“x.properties”, “write”),即对 “x.properties”的写权限。于是它先获取调用过程上下文中所有类(main(JVM)-->ClassB-->ClassA-->FileOutputStream-->AccessController)的 ProtectedDomain 找出来:
JVM 从 mian 执行的,它的 ProtectedDomain 是 SystemDomain
ClassA 的 ProtectedDomain 是 ProtectedDomainA
ClassB 的 ProtectedDomain 是 ProtectedDomainB
FileInputStream 和 AccessController 的 ProtectedDomain 是 SystemDomain
把访问上下文的 ProtectedDomain 都找出来后,就逐个检查每个 ProtectedDomain 是否有 FilePermission(“x.properties”, “write”) 权限。因为在 Java 访问控制机制中,它要确保每个调用的类都有该权限才能通过检查。
于是,开始做下面检查:
1) AccessController-->SystemDomain : Java 内部代码保护域,具有所有操作权限,检查通过
2) FileInputStream-->SystemDomain : Java 内部代码保护域,具有所有操作权限,检查通过
3) ClassA-->ProtectedDomainA: 在上面的 ProtectedDomainA 模型中,我们知道它是有 FilePermission(“x.properties”, “write”) 权限的,检查通过
4) ClassB-->ProtectedDomainB: 在上面的 ProtectedDomainB 模型中,我们知道它没有 FilePermission(“x.properties”, “write”) 权限的,检查不通过
最后,给出一张简单逻辑图:
- 大小: 14.4 KB
- 大小: 10 KB
- 大小: 19 KB
- 大小: 34 KB
分享到:
相关推荐
总之,Java的JVM通过访问控制器的栈校验机制确保了代码的类型安全和访问控制,这是Java平台可靠性的重要基石。理解这一机制对于深入掌握JVM的工作原理和优化Java代码具有重要意义。通过学习和实践,开发者能够编写出...
为了准确地理解Java访问控制机制,并验证其正确性,研究人员和开发人员需要采取形式化分析的方法。 形式化分析是一种使用数学方法来证明系统属性的技术。在这种情况下,研究人员利用了Isabelle/HOL 2015这样的形式...
Java类的访问控制机制是面向对象编程中的一个重要概念,它定义了类及其成员的可见性和访问权限。本文主要探讨了Java中的`protected`继承链访问控制机制,这是Java封装特性的一个重要组成部分。下面将详细介绍这个...
在提供的"Java访问权限控制源代码"中,可能包含示例类,这些类展示了如何使用不同的访问修饰符来控制类、变量和方法的可见性。`readme.md`文件可能包含了代码的介绍和使用指南。 通过学习和理解Java的访问权限控制...
Java安全权限控制机制是Java安全体制中的一种重要机制,通过对Java安全管理器、权限类、安全策略文件、自定制权限类等底层技术的研究,程序员可以细致的控制各个安全访问权限。 Java安全管理器(SecurityManager)...
3. **安全管理器与沙箱模型**:安全管理器(Security Manager)是Java提供的用于控制程序运行时权限的组件。沙箱模型(Sandbox Model)则是Java中的一种安全策略,它限制了代码可以执行的操作范围,确保恶意代码无法...
在编程领域,特别是Java语言中,访问控制是面向对象编程的一个关键特性,它涉及到类、接口、方法和变量的可访问性。访问控制是封装的一部分,封装是面向对象编程的三大基本特征之一,另外两个是继承和多态。封装的...
Java并发控制机制是Java编程中一个非常重要的领域,它涉及到多线程环境下代码的正确性和性能优化。在Java中,为了实现高效的并发处理,开发者可以利用一系列内置的工具和概念,如synchronized关键字、volatile变量、...
Java 访问修饰符是 Java 编程语言中的一种重要机制,它控制着类、方法和变量的访问权限。访问修饰符可以分为四种:public、protected、private 和缺省(无访问修饰符)。 public 访问修饰符 public 访问修饰符是最...
- **缓存机制**:在数据访问层,如果一个方法需要频繁访问数据库,可以使用动态代理在方法执行前先检查缓存,如果缓存中有结果则直接返回,避免了不必要的数据库访问。 - **事务管理**:动态代理可以用来管理事务...
这个"Java访问权限控制源代码.zip"压缩包可能包含了示例代码,用于演示Java中的不同访问修饰符如何工作以及如何实施访问控制。现在,我们将深入探讨Java中的访问权限控制机制。 首先,Java提供了四种访问级别: 1....
这种控制机制确保了代码的封装性和安全性,防止未经授权的访问和操作。以下是对这一主题的详细探讨: 1. 访问修饰符: Java提供了四种基本的访问修饰符: - `public`: 公共访问修饰符,任何地方的任何类都可以...
本文将深入探讨如何使用Java实现远程控制功能,并结合提供的源代码进行解析。 首先,Java作为一种跨平台的编程语言,拥有丰富的库和API,能够方便地实现网络通信和多线程操作,这为构建远程控制应用提供了坚实的...
Secure SIO通过精细的访问控制策略,有效地隔离了不同执行上下文间的直接交互,增强了卡内数据和应用的安全性。 综上所述,Java卡的对象共享机制提供了一种灵活且强大的多应用支持框架,极大地提升了智能卡的实用性...
### Java同步机制浅谈 #### synchronized关键字的作用及应用 在Java多线程环境中,`synchronized`关键字扮演着至关重要的角色。它可以帮助开发者确保多线程环境下的数据一致性,防止因并发访问导致的数据错误。本...
Java提供SSL/TLS加密,以及JAAS(Java Authentication and Authorization Service)进行身份验证和授权,以确保只有授权的用户可以访问远程系统。 5. **图形用户界面(GUI)**:为了让用户能够直观地与远程系统交互...
总结来说,"windows下java访问hid设备"是一个涉及到Java、JNI、Windows系统编程和USB HID协议的复杂任务。开发者需要具备多方面的技术知识,包括Java编程、C/C++编程、USB设备驱动理解以及JNI的使用。通过这样的方式...
Java锁机制是Java多线程编程中的核心概念之一,其主要目的是确保在多线程环境下,多个线程能够安全地访问共享资源,避免数据不一致的问题。Java锁机制的发展历经了多个版本的改进,尤其是Java 5.0引入的显示锁...
在IT领域,远程控制技术是一种允许用户通过网络访问并操控另一台计算机的系统或应用程序的能力。Java作为一种跨平台的编程语言,提供了丰富的API和库,使得开发者能够实现远程控制功能,包括屏幕共享和双向通信。...
需要注意的是,反射操作私有成员(字段和方法)通常会跳过Java的访问控制,这可能导致安全问题。此外,反射操作也可能影响性能,因为它涉及到运行时的类型检查和动态代码执行。 Java反射机制还涉及到注解处理,可以...