欢迎装载请说明出处:http://blog.csdn.net/yfqnihao

本节源码:http://download.csdn.net/detail/yfqnihao/4863854

这一节,我们会简单的描述一下jvm访问控制器的栈校验机制。

这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来。

第一步,配置系统环境。(copy吧,少年)

 
  1. path=%JAVA_HOME%/bin
  2. JAVA_HOME=C:/Java/jdk1.6.0_01
  3. CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar

第二步,配置一个策略文件的运行环境。

第一个类Doer:

第二个类Friend:

第三个类Stranger:

第四个类TextFileDisplayer:

第三步,参考笔记http://blog.csdn.net/yfqnihao/article/details/8267669,把Friend和Stranger打包并签名,并放到ecplise编译目录bin/jars下,把生成的密钥存储文件放在与bin同级的目录下。(你也可以先用我上传的源码里的jar包,不过还是建议你动手练一练)

第四步,配置策略文件

第五步,新建一个类,这个类里有个主函数,用于校验类Friend,Stranger,TextFileDisplayer对于question.txt的读取权限

第六步运行,cmd窗口输入:
java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example2

说明:

从这里,我们并不能很直观的发现访问控制器的栈校验机制,看Example2的main函数,我们知道当stranger执行doYourThing的时候,会经过这么一个过程,

Example2--------->被ApplClassLoader装入到ProtectionDomian_Example2中---------------->执行main函数

TextFilDisplayer------->ApplClassLoader判断当前的线程有没有装载类TextFilDisplayer的权限---------->装载到ProtectionDomian_TextFileDisplayer中

Friend------->ApplClassLoader判断当前的线程有没有装载类TextFilDisplayer的权限-------->装载到ProtectionDomian_Friendr中()

Stranger------->ApplClassLoader判断当前的线程有没有装载类TextFilDisplayer的权限----------->装载到ProtectionDomian_Stranger中

Stranger的实例对象stranger执行doYourThing方法---->直接调用Friend的实力引用执行doYourThing方法----->Friend的实例引用直接调用TextFileDisplayer的doYourThing方法

输出question.txt的文本内容。

这个过程中,AccessControler到底是在什么时候执行的,怎么执行的呢,来看下面这个图

上面的这个图是一个AccessControlerContext,也就是访问控制器上下文,它大概了描述了,各个函数被调用的时候的保护域的压栈过程,直到栈顶结束压栈之后,它会按照先进后出的规则,AccessControler调用自己的checkPermission方法,检验每一层的权限(上面的保护域数组中,名为BOOTSTRAP保护域是系统保护域,它的权限是SecurityConstants.ALL_PERMISSION,这就意味着他什么都能够做)。AccessControler的保护域数组成员则会调用自己的implies方法,ProtectionDomain的implies方法会先查看是否有配置了策略文件,如果有的话就将当前保护域传递给Policy这个单例,由他从配置文件中取出PermissionCollection然后再调用每个Permission检验它的implies方法,如果没有设定特定的配置文件,则直接调用当前保护域中的PermissionCollecion成员的implies,再由它调用Permission的implies方法。

由于Examples2所读取的是question.txt文本,又由于我们的策略文件中,让Friend,Stranger,TextFileDisplayer都拥有它的读取权限,所以顺利的执行了。

第七步:为了验证我们的猜想是正确的,我们现在修改Example2如下

这里我们仅仅是将question.txt换成了answer.txt,而关于这个文件我们知道Stranger是没有读取的权限的,下面我们来运行它看看

第八步,cmd窗口输入java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example
     

我们再来看AccessControlerContext的图

前面的安全检查都通过了,但是到了STRANGER保护域的时候,由于Stranger'没有读取answer.txt的权限,所以implies方法抛出了一个AccessControlException。

那么AccessControler的栈校验机制能够带来什么好处呢??

答案很显然,就好像我们第七步一样,我们试图让一个没有权限的类来调用一个具有高级权限的类别,以达到“破坏”的目的,由于栈校验机制的存在,让我们的这种幻想变得不容易实现,但是不容易实现并不代表不能够实现,下面我们将来学习一个方法,这个方法叫doPrivileged(),这个方法可以帮助我们达到第七步的目的。

第九步,修改我们上面的Example类如下

我们只是将friend的初始化参数做了稍微的调整,new Friend(tfd,true)改为了new Friend(tfd,false);这个调整使得friend的doYourThing方法不是直接的执行next.doYourThing()而是通过给AccessController.doPrivileged()方法传入一个匿名内部类并重写它的run方法,在run方法里调用了next.doYourThing()。

第十步,然后我们在cmd窗口输入:java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example3


查看输出:既然成功由没有权限查看answer.txt的Strange完成了查看answer.txt的操作。这是怎么回事??我们再来看刚才表示AccessControlContext的图

由于我们在Friend中安装了doPrivileged(),所以doPrivileged()这个方法被压入栈而且是在Stranger的前面,doPrivileged()执行的时候会调用我的匿名内部类Friend$1并执行它的run方法,而run方法里执行完next.doYourThing之后,AccessControlContext将继续执行判断到doPrivileged(),它发现这是一个BootStrap的调用,那么AccessControlContext会继续执行另外一个判断,判断是谁安装了这个doPrivileged()方法,所以执行到了Freind的doYourThing(),判定它有打开answer.txt的权限,那么最后才直接把run方法的return返回出去。

就是通过这样的方式,使得我们没有权限的Stranger能够“越权"操作。

但是越权还是有条件的,如第九步,我们执行”越权“方法run的方法栈帧是嵌套在Friend的doYourThing的线程栈帧中的,由于Friend有读取answer.txt的权限,这才使得run方法有了”越狱“的机会。

第十一步,我们修改一下Example3来验证一下自己的观点

第十二步,cmd窗口输入java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example4

报出异常了,这个异常就是由于stranger$1这个内部类的方法栈帧是嵌套在stranger的doYourThing的方法栈帧中,而stranger的保护域规定了stranger这个类的对象是没有权限读取answer.txt这个文件,所以run这个方法也就没办法”越狱“。

总结:

这一节,我们学习了访问控制器校验保护域权限的过程,它采取的是栈的校验机制(先进后出),而它的每个方法调用总是线程栈帧相关的,如果我们必须要”越狱“,那预约的条件要求调用doPrivileged()方法的栈帧的至少要有执行越狱操作的权限。

java jvm学习笔记十二(访问控制器的栈校验机制)的更多相关文章

  1. java jvm学习笔记十一(访问控制器)

     欢迎装载请说明出处: http://blog.csdn.net/yfqnihao/article/details/8271665 这一节,我们要学习的是访问控制器,在阅读本节之前,如果没有前面几节的 ...

  2. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  3. java jvm学习笔记十(策略和保护域)

    欢迎转载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8271415 前面一节,我们做了一个简单的实验,来说明什么是策略文件,在文章的最后,也 ...

  4. Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

  5. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  6. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  7. Java NIO 学习笔记(二)----聚集和分散,通道到通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  8. java jvm学习笔记七(jar包的代码认证和签名)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...

  9. java jvm学习笔记二(类装载器的体系结构)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao                 在了解java虚拟机的类装载器之前,有一个概念我们是必须先知道的,就是java的沙箱,什 ...

随机推荐

  1. UNIX command Questions Answers asked in Interview

    UNIX or Linux operating system has become default Server operating system and for whichever programm ...

  2. zju 1037 Gridland(找规律,水题)

    题目链接 多写几个案例,根据数据的奇偶性,就能找到规律了 #include<stdio.h> int main() { int t,n,m; double ans; scanf(" ...

  3. java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

    上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...

  4. 【转】Wireshark:“There are no interfaces on which a capture can be done ”

    linux环境下 两种解决方案:    第一种方法:使用root用户登陆        xiaoshancun@xiaoshancun-VM500:~$ sudo wireshark    第二种方法 ...

  5. iOS 开发--开源图片处理圆角

    概述 开源项目名称:HYBImageCliped 当前版本:2.0.0 项目用途:可给任意继承UIView的控件添加任意多个圆角.可根据颜色生成图片且可带任意个圆角.给UIButton设置不同状态下的 ...

  6. java:I/O流

    I/O是input/output的缩写,即输入输出端口. 从 文件.键盘.网络 等输入到java程序,再从java程序输出到 文件.显示器.网络等 分类: 1.输入流 和 输出流2.字节流 和 字符流 ...

  7. latex 三线表

    LaTeX 处理三线表相当简单方便.用到的宏包主要是 booktabs .代码如下: 需要添加包:\usepackage{booktabs}. \documentclass{article} \use ...

  8. 在Windows 上的 Python

    在 Windows 上, 安装 Python 有两种选择. ActiveState 制作了一个 Windows 上的 Python 安装程序称为 ActivePython, 它包含了一个完整的 Pyt ...

  9. nyoj-257 郁闷的C小加(一) 前缀表达式变后缀

    郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...

  10. 从Uboot到Linux技术内幕

    1. 引言 在专用的嵌入式板子运行 GNU/Linux 系统已经变得越来越流行.一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次: 1. 引导加载程序.包括固化在固件(firmware) ...