[Java Security]Java资源访问的安全控制
来源:互联网 发布:谷歌输入法linux版 编辑:程序博客网 时间:2024/05/29 06:40
Java资源访问的安全控制
在JDK的API中经常会看到SecurityManager
的应用,例如System.getProperty
:
public static String getProperty(String key) { checkKey(key); SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPropertyAccess(key); } return props.getProperty(key);}
不了解Java安全体系的话,可能并不知道中间几行代码的具体作用。本文先简单介绍下Java安全体系中的资源访问控制机制。
1. 资源访问控制
要控制Java程序的资源访问权限,主要有两点:
一是,定义访问策略,即java policy文件,简单的说就是资源访问授权,默认的policy文件为$JAVA_HOME/jre/lib/security/java.policy
,内容如下:
// Standard extensions get all permissions by defaultgrant codeBase "file:${{java.ext.dirs}}/*" { permission java.security.AllPermission;};// default permissions granted to all domainsgrant { // Allows any thread to stop itself using the java.lang.Thread.stop() // method that takes no argument. // Note that this permission is granted by default only to remain // backwards compatible. // It is strongly recommended that you either remove this permission // from this policy file or further restrict it to code sources // that you specify, because Thread.stop() is potentially unsafe. // See the API specification of java.lang.Thread.stop() for more // information. permission java.lang.RuntimePermission "stopThread"; // allows anyone to listen on un-privileged ports permission java.net.SocketPermission "localhost:1024-", "listen"; // "standard" properies that can be read by anyone permission java.util.PropertyPermission "java.version", "read"; permission java.util.PropertyPermission "java.vendor", "read"; permission java.util.PropertyPermission "java.vendor.url", "read"; permission java.util.PropertyPermission "java.class.version", "read"; permission java.util.PropertyPermission "os.name", "read"; permission java.util.PropertyPermission "os.version", "read"; permission java.util.PropertyPermission "os.arch", "read"; permission java.util.PropertyPermission "file.separator", "read"; permission java.util.PropertyPermission "path.separator", "read"; permission java.util.PropertyPermission "line.separator", "read"; permission java.util.PropertyPermission "java.specification.version", "read"; permission java.util.PropertyPermission "java.specification.vendor", "read"; permission java.util.PropertyPermission "java.specification.name", "read"; permission java.util.PropertyPermission "java.vm.specification.version", "read"; permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; permission java.util.PropertyPermission "java.vm.specification.name", "read"; permission java.util.PropertyPermission "java.vm.version", "read"; permission java.util.PropertyPermission "java.vm.vendor", "read"; permission java.util.PropertyPermission "java.vm.name", "read";};
授予JDK的ext目录下代码全部访问权限,授予其余任意代码的一系列默认权限。
使用Java自带的policytool工具可以创建Policy文件,具体参考Policy File Creation and Management
二是,启动SecurityManager
,默认情况下Java是不启动安全检查的。运行Java程序需带上-Djava.security.manager
参数即可启动安全校验,例如:
java -Djava.security.manager SecurityTest
只此两步即可开启资源访问的授权控制。
2. 访问控制示例
编写一段代码,完成读取系统属性、读文件、写文件三个操作,示例如下:
public static void main(String[] args) throws Exception { // properties System.out.println("properties:"); String[] properties = { "os.name", "java.version", "java.home", "user.home", "java.ext.dirs" }; for (String prop : properties) { String value = System.getProperty(prop); System.out.println(prop + " = " + value); } // read file System.out.println(); System.out.println("read file:"); String file = "E:\\download\\col_iplib.txt"; BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String line = reader.readLine(); System.out.println("read line: " + line); reader.close(); // write file System.out.println(); System.out.println("write file:"); file = "E:\\download\\security-test.txt"; BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))); line = "test java security"; writer.write(line); writer.newLine(); System.out.println("write line: " + line); writer.close();}
在不开启安全检查时,可以正常运行,结果如下:
E:\workspace\proj\alg\target\classes>java com.github.myron.security.SecurityTestproperties:os.name = Windows 7java.version = 1.8.0_40java.home = C:\Program Files\Java\jre1.8.0_40user.home = C:\Users\gengmaozhang01java.ext.dirs = C:\Program Files\Java\jre1.8.0_40\lib\ext;C:\windows\Sun\Java\lib\extread file:read line: 1.0.1.0|1.0.3.255:CN|福建|None|None|CHINANET|None|Nonewrite file:write line: test java security
当开启安全检查时,即会报错。
E:\workspace\proj\alg\target\classes>java -Djava.security.manager com.github.myron.security.SecurityTestproperties:os.name = Windows 7java.version = 1.8.0_40Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.home" "read") at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPropertyAccess(Unknown Source) at java.lang.System.getProperty(Unknown Source) at com.github.myron.security.SecurityTest.main(SecurityTest.java:30)
因为Java默认的java.policy文件并未授予所有程序读取java.home的权限,及文件读写权限。
使用policytool工具创建自己的policy文件,授予上述系统属性、文件读写的权限,如下:
生成的policy文件如下:
/* AUTOMATICALLY GENERATED ON Sun Oct 23 20:30:42 CST 2016*//* DO NOT EDIT */grant codeBase "file:/E:/workspace/proj/alg/target/classes/*" { permission java.io.FilePermission "<<ALL FILES>>", "read, write"; permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "user.home", "write, read"; permission java.util.PropertyPermission "java.ext.dirs", "read";};
使用-Djava.security.policy
参数指定该policy策略,执行正常:
E:\workspace\proj\alg\target\classes>java -Djava.security.manager -Djava.security.policy=E:/download/my.java.policy com.github.myron.security.SecurityTestproperties:os.name = Windows 7java.version = 1.8.0_40java.home = C:\Program Files\Java\jre1.8.0_40user.home = C:\Users\gengmaozhang01java.ext.dirs = C:\Program Files\Java\jre1.8.0_40\lib\ext;C:\windows\Sun\Java\lib\extread file:read line: 1.0.1.0|1.0.3.255:CN|福建|None|None|CHINANET|None|Nonewrite file:write line: test java security
3. 自定义权限控制
在具体项目中,除了常见的系统资源,还有其他业务资源需要进行访问控制,这里就以消息服务为例来演示自定义的权限控制。
首先,定义自己的资源权限,如下:
public class MessagePermission extends BasicPermission { private static final long serialVersionUID = -6179037573716029507L; public static final String MESSAGE_READ_ACTION = "readMessage"; public static final String MESSAGE_WRITE_ACTION = "writeMessage"; private String actions; public MessagePermission(String name) { super(name); } public MessagePermission(String name, String actions) { // NOTE: actions is ignored by BasicPermission super(name, actions); this.actions = actions; } @Override public String getActions() { return actions; } // 简单的Actions比较实现,更精细的实现可参考PropertyPermission @Override public boolean implies(Permission p) { if (super.implies(p)) { MessagePermission mp = (MessagePermission) p; if (mp.getActions() == null || mp.getActions().isEmpty()) { return true; } if (this.actions == null || this.actions.isEmpty()) { return false; } if (this.actions.contains(mp.getActions())) { return true; } return false; } return false; }}
然后,编写有安全校验的消息读写程序,代码如下:
public class SecurityMessageService { public static final String MESSAGE_NAME = "SecurityMessage"; public void readMessage() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new MessagePermission(MESSAGE_NAME, MessagePermission.MESSAGE_READ_ACTION)); } // do something System.out.println("read message done"); } public void writeMessage() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new MessagePermission(MESSAGE_NAME, MessagePermission.MESSAGE_WRITE_ACTION)); } // do something System.out.println("write message done"); } public static void main(String[] args) { SecurityMessageService messageService = new SecurityMessageService(); // read messageService.readMessage(); // write messageService.writeMessage(); }}
直接开启安全检查执行,抛出了无消息读写权限的异常:
E:\workspace\proj\alg\target\classes>java -Djava.security.manager com.github.myron.security.SecurityMessageServiceException in thread "main" java.security.AccessControlException: access denied ("com.github.myron.security.MessagePermission" "SecurityMessage" "readMessage") at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at com.github.myron.security.SecurityMessageService.readMessage(SecurityMessageService.java:17) at com.github.myron.security.SecurityMessageService.main(SecurityMessageService.java:36)
最后,创建policy策略文件,授予消息读写权限,如下:
/* AUTOMATICALLY GENERATED ON Sun Oct 23 22:17:00 CST 2016*//* DO NOT EDIT */grant codeBase "file:/E:/workspace/proj/alg/target/classes/*" { permission com.github.myron.security.MessagePermission "SecurityMessage", "readMessage,writeMessage";};
执行正常完成,结果如下:
E:\workspace\proj\alg\target\classes>java -Djava.security.manager -Djava.security.policy=E:/download/message.policy com.github.myron.security.SecurityMessageServiceread message donewrite message done
参考:
1. Trail: Security Features in Java SE
2. 自定义java.policy配置
3. Java程序访问权限控制(policy文件)
- [Java Security]Java资源访问的安全控制
- 多线程访问 资源的安全控制
- 多线程访问 资源的安全控制
- 多线程访问 资源的安全控制
- Java中怎么控制线程访问资源的数量
- java-实现资源访问的超时和并发控制
- Java的访问控制
- Java的访问控制
- java的访问控制
- Java安全管理器Security Manager
- Java安全管理器(Security Manager)
- Java安全管理器(Security Manager)
- Java安全管理器(Security Manager)
- 【数字安全】Security in Java
- JAVA类的访问控制
- java的访问控制符
- Java访问权限的控制
- Java的访问控制符
- Shell脚本笔记
- insertsort
- Android入门第八篇之GridView(九宫图)
- Spark RDD部分算子应用案例
- linuxc编程学习
- [Java Security]Java资源访问的安全控制
- 值得收藏的网站之颜色选择
- Android Studio设置代理&&卡在启动界面解决方法
- HTML5,canvas中的线型属性lineCap设置之后没有效果!
- 包及访问控制权限
- sql语法:inner join on, left join on, right join on详细使用方法
- Swift3.0 tableView/CollectionView点击事件与手势的冲突
- Linux下fork()、vfork()、clone()和exec()的区别
- 【HTML/CSS】CSS层叠样式表常用格式