使用 SecurityManager 和 Policy File 管理 Java 程序的权限
参考资料
该文中的内容来源于 Oracle 的官方文档。Oracle 在 Java 方面的文档是非常完善的。对 Java 8 感兴趣的朋友,可以从这个总入口 Java SE 8 Documentation 开始寻找感兴趣的内容。本博客不定期从 Oracle 官网搬砖。
前言
Java 在 Security 方面的特性,总是被很多人当做宣传的重点,但是对我而言,这基本上是八百年都用不到一次的特性。可是没办法,为了知识体系的完整性,我也不得不硬着头皮学习这些八竿子都打不着的内容。
很多 Java 程序默认在一个安全的环境中运行,比如 Applet程序。当这些在安全环境中运行的程序需要访问我们系统中的资源时,就会受到限制。换句话说,就是当 Applet 之类的程序运行时,默认就会启动一个 SecurityManager,SecurityManager 负责检查该程序是否具有相应的权限。但是很多 Java 程序不会默认启动 SecurityManager,比如大部分在我们系统中直接运行的 Java 程序。没有启用 SecurityManager 的程序的权限不会受到限制,如果存在恶意代码的话,就会产生安全问题。如果我们非要放宽对它们的限制的话,就需要对相应的 Java 程序进行授权,授权需要用到 Policy File。
没有启用 SecurityManager 的程序可以访问系统中的任意资源
废话少说,直接开始实战。先看两个示例程序,GetProps.java 和 Count.java,它们一个需要访问 Java 运行环境中的 Properties,一个需要读取磁盘上的文件。代码如下图:


编译、打包、运行,这两个程序的运行结果非常符合预期,如下图:

从上图中可以看出,我在打包的时候没有使用 jar 的 -e 选项指定程序的入口点,只是简单的把所有的 .class 打成一个 jar 包而已。运行的时候使用 java -cp HelloWorld.jar 将该 jar 包指定为 CLASSPATH 并直接运行其中的类。其实这里的程序不打包也可以运行,但是要对程序进行签名,就必须得打包了。
启用了 SecurityManager 的程序权限会被限制
如果启用 SecurityManager,则程序的权限会受到限制。怎么启用 SecurityManager 呢?有两个办法,一个办法是在启动程序的使用使用 java -Djava.security.manager 选项,另一个办法是在代码中使用 System.setSecurityManager(new SecurityManager());。先看下图,使用第一种办法开启 SecurityManager:

可以看到,一旦使用 java -Djava.security.manager 选项启动,程序 GetProps 和 Count 都产生了异常。我们也可以在代码中启用 SecurityManager,也可以手动调用 SecurityManager 的方法来验证运行的程序是否具有相应的权限。请看下图示例程序 SecurityOnByCode.java:

编译、打包、运行,果然产生了异常,如下图:

使用 Policy File 为程序授权
如果要让启用了 SecurityManager 的程序正常运行,就必须对它们进行相应的授权。在本例中,需要对 GetProps 和 SecurityOnByCode 示例程序授予它访问 System Properties 的权限,为 Count 示例程序授予访问目录 src/com/xkland/sample 中文件的权限。授权是使用 Policy File 来控制的。系统中有一个全局的 Policy File,它的路径是 ${java.home}/lib/security/java.policy,另外还可以为当前用户定义一个用户级别的 Policy File,只要这个文件的路径是 ${user.home}/.java.policy 就行。也可以编写其它的任意的 Policy File,只需要在启动程序的时候用 java -Djava.security.policy= 选项指定 Policy File 的路径即可。
在 JDK 提供的工具中,有一个 policytool,这是一个 GUI 程序,它可以极大地简化我们编写 Policy File 的过程,后面的实战中会用到它。首先,先来为需要访问 System Properties 的程序授权,我制定一个这样的策略:位于 ${user.home}/HelloJavaWorld 目录下的程序可以访问 System Properties,这就需要用到基于 CodeBase 的授权。在本例中,我使用 policytool 创建一个 youxia.policy 文件,并基于 CodeBase 授予相应的访问 System Properties 的 java.util.PropertyPermission,如下图:

可以使用 cat youxia.policy 命令查看生成的 Policy File 的内容。授权之后再运行 GetProps 程序和 SecurityOnByCode 程序,发现它们都能顺利运行,没有产生任何异常,如下图:

但是另外一个程序 Count 仍然受限的,因为我们没有给它授予访问文件的权限。下面来解决这个问题,我设计的策略是如果该程序是被 youxia 的证书签名的,则授予它访问 src/com/xkland/sample 目录下所有文件的权利。这就需要用到基于 SignedBy 的授权。使用该类型的授权必须先指定密钥库(keystore),而密钥库的类型、供应方和口令是可以留空的,如下图:

然后再添加相应的授权,如下图:

最后来看运行效果。先常规使用 cat youxia.policy 看看,发现 Policy File 中多了一个 Grant SignedBy "youxia" 的条目,然后对 HelloWorld.jar 使用 youxia 的证书进行签名,最后运行程序,结果一切正常。如下图:

总结
Java 领域中一些关于安全的特性往往是商家宣传的重点,但是对于我们普通开发者而言,用到这些特性的机会很少,因此往往会比较陌生。关于证书和密钥库的内容,请看这里 JDK中的证书生成和管理工具keytool, 关于 jar 文件签名和验证的内容,请看这里 Java程序的打包、签名和验证。这一篇中涉及到的 SecurityManager 和 Policy File 本身并不难,按我这个实战的流程走一遍即可了然于胸。
使用 SecurityManager 和 Policy File 管理 Java 程序的权限的更多相关文章
- Java 监控基础 - 使用 JMX 监控和管理 Java 程序
点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码网站 已经收录,有很多知识点和系列文章. 此篇文 ...
- JMX——以可视化形式管理与监控正在运行中的Java程序
简单理解: MBean:管理的最小单元,一个MBean就是一个可以被监控的JavaBean. MBeanServer:一个池子,各个MBean都会注册到该池子中,并且该池子提供一系列的管理.监控API ...
- Java程序员必须熟知的十项技术
1.语法 Java程序员必须比较熟悉语法,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息知道是什么样的语法错误并且知道任何修正. 2.命令 必须熟悉JDK带的一些常用命令及其常用选项,命 ...
- Linux上Makefile管理java项目
前面文章讲到了Linux上通过.spec文件与rpmbuild命令将java程序打包为RPM安装包, 现阶段遇到新的需求: 使用Makefile来操纵java的编译.打包 该需求以前面的内容为基础 可 ...
- 读书笔记一 Java程序员的基本修养(数组及其内存管理)
1.1 数组初始化 1.1.1 java数组是静态的 java数组被初始化之后,该数组所占的内存空间.数组长度都是不可变的. java程序中的数组必须经过初始化才可使用. 数组的初始化有两种方式: 1 ...
- spark之java程序开发
spark之java程序开发 1.Spark中的Java开发的缘由: Spark自身是使用Scala程序开发的,Scala语言是同时具备函数式编程和指令式编程的一种混血语言,而Spark源码是基于Sc ...
- [转载]一个标准java程序员的进阶过程
第一阶段:Java程序员 技术名称 内 容 说明 Java语法基础 基本语法.数组.类.继承.多态.抽象类.接口.object对象.常用类(Math\Arrarys\S ...
- Java程序性能优化Tip
本博客是阅读<java time and space performance tips>这本小书后整理的读书笔记性质博客,增加了几个测试代码,代码可以在此下载:java时空间性能优化测试代 ...
- 《Java程序员修炼之道》
原子类:java.util.concurrent.atomic 线程锁:java.util.concurrent.locks 对付死锁:boolean acquired = lock.tryLock( ...
随机推荐
- JavaScript中Math对象的方法介绍
1.比较最值方法 比较最值有两种方法,max() 和 min() 方法. 1.1 max() 方法,比较一组数值中的最大值,返回最大值. var maxnum = Math.max(12,6,43,5 ...
- AutoMapper:Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html 应用场景:ViewModel==>Mode映射的时候出错 AutoMappe ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
- 漫谈TCP
不得不承认,tcp是一个非常复杂的协议.它包含了RFC793及之后的一些协议.能把tcp的所有方面面面具到地说清楚,本身就是个很复杂的事情.如果再讲得枯燥,那么就会更让人昏昏欲睡了.本文希望能尽量用稍 ...
- C# 索引器,实现IEnumerable接口的GetEnumerator()方法
当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...
- bzoj3932--可持久化线段树
题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...
- Android之三种网络请求解析数据(最佳案例)
AsyncTask解析数据 AsyncTask主要用来更新UI线程,比较耗时的操作可以在AsyncTask中使用. AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法. ...
- SQLServer如何添加try catch
在.net中我们经常用到try catch.不过在sqlserver中我们也可以使用try catch捕捉错误,在这里把语法记录下来和大家分享一下, --构建存储过程CREATE PROCEDURE ...
- CentOS 7 修改主机名
今天在阿里云上买了一个centos7的服务器,连接上以后,发现一个很长很长的主机名,看着让人很是不爽,就想着怎样将其改成一个有个性的名字. 这里我想说的是,在centos7 版本的linux系统上和c ...
- ASP.NET Aries JSAPI 文档说明:AR.Form、AR.Combobox
AR.Form 文档 1:对象或属性: 名称 类型 说明 data 属性 编辑页根据主键请求回来的数据 method 属性 用于获取数据的函数指向,默认值Get objName 属性 用于拦截form ...