前言:
安全管理器和类装载器都可以自定义,安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控制器AccessController的栈检查机制又遍历整个PerssiomCollection来判断具体拥有什么权限一旦发现栈中一个权限不允许的时候抛出异常否则简单的返回,这个过程实际上比描上述描述要复杂得多,这里仅仅举个例子,
有个形象思维。
实现:
第一步,定义一个类继承自SecurityManger重写它的checkRead方法:
public class MySecurityManager extends SecurityManager { @Override public void checkRead(String file) { //super.checkRead(file, context); if (file.endsWith("test")) throw new SecurityException("你没有读取的本文件的权限"); } }
第二步,定义一个有main函数的public类来验证自己的安全管理器是不是器作用了。
import java.io.FileInputStream; import java.io.IOException; public class TestMySecurityManager { public static void main(String[] args) { System.setSecurityManager(new MySecurityManager()); try { FileInputStream fis = new FileInputStream("test"); System.out.println(fis.read()); } catch (IOException e) { e.printStackTrace(); } } }
第三步,运行代码查看控制台输出:
java.lang.SecurityException: 你没有读取的本文件的权限 at MySecurityManager.checkRead(MySecurityManager.java:7) at java.io.FileInputStream.<init>(Unknown Source) at java.io.FileInputStream.<init>(Unknown Source) at TestMySecurityManager.main(TestMySecurityManager.java:10)
上面的异常我们发现,安全管理器起作用了, 在 《 jvm_7_安全管理器简介》中使用的是-Djava.security.manager安装过默认的安全管理器, 这里使用自定义安全器。
拓展内容:
为何要重写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(); } fd = new FileDescriptor(); open(name); }
文件流创建时候先 执行SecurityManager security = System.getSecurityManager();,然后再调用security的checkRead方法, 因此上面 重写了checkRead方法。
SecurityManager 的应用很广,如下案例(java的File.setWritable方法), 下面就使用了SecurityManager的checkWrite方法,如果我们想通过checkWrite验证自定义安全管理器是否应用到类中时, 还需要重写 checkWrite方法
public boolean setWritable(boolean writable, boolean ownerOnly) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(path); } return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly); }