(转载)Spring源码--关于AccessController.doPrivileged

来源:互联网 发布:电子书编辑软件下载 编辑:程序博客网 时间:2024/06/06 12:39

原文链接

在Spring里发现一段代码,位置在DefaultListableBeanFactory -> preInstantiateSingletons()方法里。
如下:

if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {    isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {        public Boolean run() {            return ((SmartFactoryBean<?>) factory).isEagerInit();        }    }, getAccessControlContext());}

对于这个AccessController.doPrivileged,表示完全不懂是怎么回事。现在具体分析一下。

场景

当一个代码片段加载到现有的系统中,如果不对这个代码加以访问控制,那么它极有可能对当前系统安全造成破坏。比如这段代码会偷偷读取磁盘上的所有文件,然后保存到另外一台服务器上,造成机密信息泄露。
最常见的就是applet程序,它会被限制在一个沙箱里运行。或者导入其他jar包到系统,而这个jar包中的程序也有可能是恶意的。
所以,如果对这些代码进行权限控制是理所当然的。

安全管理器SecurityManager

作用是用于检查代码执行权限。其实日常的很多API都涉及到安全管理器,它的工作原理一般是:
1. 请求Java API
2. Java API使用安全管理器判断许可权限
3. 通过则顺序执行,否则抛出一个Exception

经典的FileInputStream,会调用SecurityManager的checkRead方法,用于检查是否有读取某个文件的权限。

public FileInputStream(File file) throws FileNotFoundException {    String name = (file != null ? file.getPath() : null);    SecurityManager security = System.getSecurityManager();    if (security != null) {        security.checkRead(name);    }    if (name == null) {        throw new NullPointerException();    }    if (file.isInvalid()) {        throw new FileNotFoundException("Invalid file path");    }    fd = new FileDescriptor();    fd.incrementAndGetUseCount();    this.path = name;    open(name);}

SecurityManager里的方法列表如下,

checkAccept(String, int)checkAccess(Thread)checkAccess(ThreadGroup)checkAwtEventQueueAccess()checkConnect(String, int)checkConnect(String, int, Object)checkCreateClassLoader()checkDelete(String)checkExec(String)checkExit(int)checkLink(String)checkListen(int)checkMemberAccess(Class<?>, int)checkMulticast(InetAddress)checkMulticast(InetAddress, byte)checkPackageAccess(String)checkPackageDefinition(String)checkPermission(Permission)checkPermission(Permission, Object)checkPrintJobAccess()checkPropertiesAccess()checkPropertyAccess(String)checkRead(FileDescriptor)checkRead(String)checkRead(String, Object)checkSecurityAccess(String)checkSetFactory()checkSystemClipboardAccess()checkTopLevelWindow(Object)checkWrite(FileDescriptor)checkWrite(String)

都是check方法,分别囊括了文件的读写删除和执行、网络的连接和监听、线程的访问、以及其他包括打印机剪贴板等系统功能。而这些check代码也基本横叉到了所有的核心Java API上。

访问控制器AccessController

上面的SecurityManager都是基于AccessController实现的,还是继续上面的FileInputStream。
security.checkRead()方法的细节,

public void checkRead(String file) {    checkPermission(new FilePermission(file,        SecurityConstants.FILE_READ_ACTION));}

checkPermission()的细节,

public void checkPermission(Permission perm) {    java.security.AccessController.checkPermission(perm);}

可以看出,SecurityManager会调用AccessController里的方法。

概念


需要理解4个概念:代码源、权限、策略和保护域。


代码源CodeSource

CodeSource就是一个简单的类,用来声明从哪里加载类。


权限Permission

Permission类是AccessController处理的基本实体。Permission类本身是抽象的,它的一个实例代表一个具体的权限。权限有两个作用,一个是允许Java API完成对某些资源的访问。另一个是可以为自定义权限提供一个范本。权限包含了权限类型、权限名和一组权限操作。具体可以看看BasicPermission类的代码。典型的也可以参看FilePermission的实现。


策略Policy

策略是一组权限的总称,用于确定权限应该用于哪些代码源。话说回来,代码源标识了类的来源,权限声明了具体的限制。那么策略就是将二者联系起来,策略类Policy主要的方法就是getPermissions(CodeSource)和refresh()方法。Policy类在老版本中是abstract的,且这两个方法也是。在jdk1.8中已经不再有abstract方法。这两个方法也都有了默认实现。

在JVM中,任何情况下只能安装一个策略类的实例。安装策略类可以通过Policy.setPolicy()方法来进行,也可以通过java.security文件里的policy.provider=sun.security.provider.PolicyFile来进行。jdk1.6以后,Policy引入了PolicySpi,后续的扩展基于SPI进行。


保护域ProtectionDomain

保护域可以理解为代码源和相应权限的一个组合。表示指派给一个代码源的所有权限。看概念,感觉和策略很像,其实策略要比这个大一点,保护域是一个代码源的一组权限,而策略是所有的代码源对应的所有的权限的关系。

JVM中的每一个类都一定属于且仅属于一个保护域,这由ClassLoader在define class的时候决定。但不是每个ClassLoader都有相应的保护域,核心Java API的ClassLoader就没有指定保护域,可以理解为属于系统保护域。

使用方法


这是一个无法实例化的类——仅仅可以使用其static方法。

checkPermission

AccessController最重要的方法就是checkPermission()方法,作用是基于已经安装的Policy对象,能否得到某个权限。

doPrivileged

还有一个方法,就是doPrivileged()方法,获取特权,用于绕过权限检查。

参考

Java安全——安全管理器、访问控制器和类装载器
Java 授权内幕

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 登登山蚂蚱 养殖蚂蚱成本及利润 蚂蚱好养吗 养一亩蚂蚱的利润 梦见蚂蚱是什么意思 蚂蚱怎么养殖 养蚂蚱 养殖蚂蚱 蚂蚱养殖大棚 蚂蚱养殖网 蚂蚱种苗价格 蚂蚱的养殖方法 蚂蚱 养殖 蚂蚱批发价 蚂蚱养殖效益 蚂蚱的养殖 大蚂蚱 如何养蚂蚱 蚂蚱和蝗虫的区别 小蚂蚱 人工养蚂蚱 养蚂蚱怎么养 蚂蚱打野 尖头蚂蚱 蚂蚱收购价格 那里收购蚂蚱 哪里收购蚂蚱 木蚂蚱 蚂蚱怎么吃 小蚂蚱摩托车价格 蚂蚱越野车 养蚂蚱的技术 蚂蚱歌曲 观察蚂蚱 蚂蚱几条腿 什么打蚂蚱好打 吃蚂蚱过敏 蝈蝈和蚂蚱区别 蚂蚱演员表 养殖蚂蚱的利润 蚂蚱可以吃吗