Java默认不打开安全检查,如果不打开,本地程序拥有所有权限。

但是如果程序中加了

System.setSecurityManager(new SecurityManager());

则Java程序会检验权限。

假设有这样一种情况:A程序想在 C:\\Users\\taohuan\\Desktop\\test1  这个目录中新建一个文件,但是它没有相应的权限,但是它引用了另外一个Jar包B,刚好B有权限在C:\\Users\\taohuan\\Desktop\\test1目录中新建文件,还有更巧的是B在新建文件的时候采用的是AccessController.doPrivileged方法进行的,这种情况下,A就可以调用B的创建文件的方法进行创建文件了。

下面举一个例子。

新建一个B工程,名字为demo-core,所在路径为:D:\\Tao\\Project\\my-demo\\demo-parent\\demo-core,是一个简单的jar包程序,新建一个类PrivilegedFileUtil

package com.mydemo;import java.io.File;
import java.io.IOException;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedAction;/*** @author taohuan*/
public class PrivilegedFileUtil {public static boolean canRead(String fileName) {try {// 尝试普通方式创建一个新文件File fs = new File(fileName);return fs.canRead();} catch (AccessControlException e) {e.printStackTrace();}return false;}public static void makeFile(String fileName) {try {// 尝试普通方式创建一个新文件File fs = new File(fileName);fs.createNewFile();} catch (AccessControlException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public static void doPrivilegedAction(final String fileName) {// 用特权访问方式创建文件AccessController.doPrivileged(new PrivilegedAction<String>() {@Overridepublic String run() {makeFile(fileName);return null;}});}
}

再新建一个另一个工程A,名字为demo-main,所在路径为:D:\\Tao\\Project\\my-demo\\demo-parent\\demo-main,并且引用demo-core工程,

<dependency>
    <groupId>com.mydemo</groupId>
    <artifactId>demo-core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

新建一个类AccessControllerTest

package com.mydemo.test;import com.mydemo.PrivilegedFileUtil;import java.security.AccessControlException;/*** @author taohuan*/
public class AccessControllerTest {public static void main(String[] args) {// 打开系统安全权限检查开关System.setSecurityManager(new SecurityManager());try {String pathName = "C:\\Users\\taohuan\\Desktop\\test1\\test-path-product-1.txt";System.out.println(PrivilegedFileUtil.canRead(pathName));}catch (AccessControlException e1) {e1.printStackTrace();}try {String pathName = "C:\\Users\\taohuan\\Desktop\\test1\\test-wtite.txt";PrivilegedFileUtil.makeFile(pathName);} catch (AccessControlException e1) {e1.printStackTrace();}try {String pathName = "C:\\Users\\taohuan\\Desktop\\test1\\test-wtite-use-Privileged.txt";PrivilegedFileUtil.doPrivilegedAction(pathName);} catch (AccessControlException e1) {e1.printStackTrace();}}}

1、此时直接运行AccessControllerTest的main方法,发现会报错,没有权限

2、在demo-main工程的根路径下新建MyPolicy.txt文件

//授权D:\\Tao\\Project\\my-demo\\demo-parent\\demo-core\\target\\classes 下所有jar包或class类 可以读取和写入C:\\Users\\taohuan\\Desktop\\下所有文件grant codebase "file:D:\\Tao\\Project\\my-demo\\demo-parent\\demo-core\\target\\classes"{permission java.io.FilePermission"C:\\Users\\taohuan\\Desktop\\test1\\*", "read,write";};

在运行AccessControllerTest时添加vm参数

-Djava.security.policy=D:/Tao/Project/my-demo/demo-parent/demo-main/MyPolicy.txt

此时在运行发现test-wtite-use-Privileged.txt文件能够创建出来。

可以看到test-wtite-use-Privileged.txt文件创建的时候采用的是

// 用特权访问方式创建文件
AccessController.doPrivileged(new PrivilegedAction<String>() {@Override
    public String run() {makeFile(fileName);
        return null;
    }
});

之所以能够创建出来,因为PrivilegedFileUtil有写C:\\Users\\taohuan\\Desktop\\test1  目录的权限,并且采用了AccessController.doPrivileged方式。

这里还可以看到即使PrivilegedFileUtil有读C:\\Users\\taohuan\\Desktop\\test1  目录的权限,但是读的时候并没有采用AccessController.doPrivileged的方式,所以还是会判定为没有权限,抛了异常。

总结一下:

类java.security.AccessController提供了一个默认的安全策略执行机制,它使用栈检查来决定潜在不安全的操作是否被允许。

这个访问控制器不能被实例化,它不是一个对象,而是集合在单个类中的多个静态方法。

 如果你安装了具体安全管理器,其实最终是由这个AccessController来决定一个潜在不安全的方法是否否被允许。
     每一个栈帧代表了由当前线程调用的某个方法,每一个方法是在某个类中定义的,每一个类又属于某个保护域,每个保护域包含一些权限。

因此,每个栈帧间接地和一些权限相关。

AccessController 类用于与访问控制相关的操作和决定。

更确切地说,AccessController 类用于以下三个目的:

  • 基于当前生效的安全策略决定是允许还是拒绝对关键系统资源的访问
  • 将代码标记为享有“特权”,从而影响后续访问决定,以及
  • 获取当前调用上下文的“快照”,这样便可以相对于已保存的上下文作出其他上下文的访问控制决定。

checkPermission 方法确定应该批准还是拒绝由指定权限所指示的访问请求。示例调用如下所示。在此例中,checkPermission 将确定是否批准对 "/temp" 目录中名为 "testFile" 的文件的“读”访问。

 FilePermission perm = new FilePermission("/temp/testFile", "read");AccessController.checkPermission(perm);

如果允许执行请求的访问,则 checkPermission 正常返回。如果拒绝,则抛出 AccessControlException。如果请求的权限类型不正确或包含无效值,也会抛出 AccessControlException。只要有可能,都会给出此类信息。假定当前线程按照调用方 1 到调用方 2 直到调用方 m 的顺序遍历了 m 个调用方。那么调用方 m 调用 checkPermission 方法。checkPermission 方法基于以下算法确定是批准还是拒绝进行访问:

 i = m;while (i > 0) {if (caller i's domain does not have the permission)throw AccessControlExceptionelse if (caller i is marked as privileged) {if (a context was specified in the call to doPrivileged) context.checkPermission(permission)
return;}i = i - 1;};// Next, check the context inherited when// the thread was created. Whenever a new thread is created, the// AccessControlContext at that time is// stored and associated with the new thread, as the "inherited"
// context.inheritedContext.checkPermission(permission);

可以将调用方标记为享有“特权”。在做访问控制决定时,如果遇到通过调用不带上下文参数(请参阅下文,以获取关于上下文参数的信息)的 doPrivileged 标记为“特权”的调用方,则 checkPermission 方法将停止检查。如果该调用方的域具有指定的权限,则不进行进一步检查,并且 checkPermission 正常返回,指示允许所请求的访问。如果该域不具有指定的权限,则通常抛出异常。

在某一个线程的调用栈中,当 AccessController 的 checkPermission 方法被最近的调用程序调用时,对于程序要求的所有访问权限,ACC 决定是否授权的基本算法如下:
1. 如果调用链中的某个调用程序没有所需的权限,将抛出 AccessControlException;
2. 若是满足以下情况即被授予权限:
    a. 调用程序访问另一个有该权限域里程序的方法,并且此方法标记为有访问“特权”;
    b. 调用程序所调用(直接或间接)的后续对象都有上述权限。

AccessController的doPrivileged使用相关推荐

  1. Java 授权内幕--转载

    在信息安全性领域,授权是世界的的中心,因为它是控制个体(即人.进程和计算机)对系统资源的访问权限的过程.直到最近,在 Java 安全体系结构中相关的问题都是"这段运行中的代码的访问权限是什么 ...

  2. java堆栈信息查看,以及JVM性能查看工具-jconsole+jmap

    java-core  P487 P515 chapter11,主要讲java的异常,里面很多内容收获良多,之前一直没注意过的. 一,Throwable类获得StackTraceElement ,可进行 ...

  3. JavaSecurity和JAAS——Java标准安全体系概述(上)

    前言:java标准安全体系分为两大部分,一个是在JDK1.0引入并在JDK2进行了重构的代表着以代码为中心的授权体系.此体系下,关注的重点在于"这段代码能访问哪些系统资源":另一个 ...

  4. Java 深度历险(作者成富,是IBM 中国软件开发中心的高级工程师)

    Java 深度历险(作者成富,是IBM 中国软件开发中心的高级工程师)  http://blog.csdn.net/hnzhangshilong/article/details/7038009 2  ...

  5. java 的 AccessController.doPrivileged使用

    http://huangyunbin.iteye.com/blog/1942509 AccessController.doPrivileged意思是这个是特别的,不用做权限检查. 在什么地方会用到呢: ...

  6. java doprivileged_【转】关于AccessController.doPrivileged

    在查看socket源码时发现在getInputStream()这个方法里有这种写法,之前没有遇到过,做个记录. 搬运自这里; 最近在看一些框架代码,偶尔都会遇到AccessController.doP ...

  7. AccessController.doPrivileged

    转自: http://blog.csdn.net/jiaotuwoaini/article/details/70176021 在某一个线程的调用栈中,当 AccessController 的 chec ...

  8. jvm之AccessController.doPrivileged

    AccessController.doPrivileged在底层源码中会出现,本文对它进行一个简单介绍及如何使用的说明. 首先解释一下几个相关概念 保护域 类被装入jvm,为每个类指定一个保护域,保护 ...

  9. Java安全:SecurityManager与AccessController

    前言 什么是安全? 程序不能恶意破坏用户计算机的环境,比如特洛伊木马等可自我进行复制的恶意程序. 程序不可获取主机及其所在网络的私密信息. 程序的提供者和使用者的身份需要通过特殊验证. 程序所涉及的数 ...

  10. HttpUrlConnection底层实现和关于java host绑定ip即时生效的设置及分析

    最近有个需求需要对于获取URL页面进行host绑定并且立即生效,在java里面实现可以用代理服务器来实现:因为在测试环境下可能需要通过绑定来访问测试环境的应用 实现代码如下: public stati ...

最新文章

  1. java 数组的动态初始化和静态初始化
  2. Modelsim仿真时不能编译`include文件解决办法
  3. 十个经典Java 集合面试题!
  4. 【阿里内部应用】基于Blink为新商业调控打造实时大数据交互查询服务
  5. 荣耀20/20 Pro相机规格曝光:DxOMark排名或将再次改变
  6. SFS2X客户端全部事件详细
  7. 办公利器:IBM Lotus Symphony轻松之旅
  8. 第三章、获取书籍信息
  9. 范式哈夫曼编码(Canonical Huffman Code)
  10. 深入浅出看懂AlphaGo Zero (文章最后有原AlphaGo Zero论文地址)
  11. 麦肯锡高管的逻辑树分析大法!
  12. 《数学之美》——吴军#读书笔记
  13. Three.js(2)--->基础篇-Helpers(辅助对象/辅助线)
  14. OpenGL总结6-圆柱纹理贴图
  15. 不要看《深入浅出MFC》!
  16. 时间戳转换成标准日期
  17. 对Restful的理解
  18. ThreadX 实时操作系统
  19. 【Redis】Key的层级结构
  20. 城市简码_如何使用简码在WordPress中添加Twitter Bootstrap CSS

热门文章

  1. 可以实现树形结构的设计模式(组合模式)
  2. AutoCAD快速入门(二十九):视口
  3. 新手试炼:C语言实现加密版2-4阶行列式运算!
  4. FSR402传感器简介
  5. 微信开放平台、公众号和小程序的总结
  6. 微信缓存css怎么清理,前端清除缓存方法(微信缓存引起的bug)
  7. 网络技术——路由器及其配置
  8. 怪物之心无法触发_《异度之刃2》稀有异刃力男怪物之心支线任务攻略
  9. Pyspark 案例实践 假新闻分类
  10. lingo入门教程之二 --- 集合运用