下面是一个示例调用,它使用了以前示例中获得的 SecurityManager sm:if (sm != null) sm.checkPermission(permission, context); 权限分为以下类别:文件、套接字、网络、安全性、运行时、属性、AWT、反射和可序列化。管理各种权限类别的类是 java.io.FilePermission、 java.net.SocketPermission、 java.net.NetPermission、 java.security.SecurityPermission、 java.lang.RuntimePermission、 java.util.PropertyPermission、 java.awt.AWTPermission、 java.lang.reflect.ReflectPermission java.io.SerializablePermission 除前两个(FilePermission 和SocketPermission)类以外的所有类都是 java.security.BasicPermission 的子类, 而java.security.BasicPermission 类又是顶级权限类 java.security.Permission 的抽象子类. BasicPermission 定义了所有权限所需的功能, 这些功能的名称遵从分层属性命名惯例(例如“exitVM”、“setFactory”、“queuePrintJob”等等)。 在名称的末尾可能出现一个星号,前面是“.”或星号,这表示通配符匹配。例如:“a.*”、“*”是有效的,而“*a”或“a*b”是无效的。 FilePermission 和SocketPermission 是顶级权限类 (java.security.Permission) 的子类。像这些命名语法比 BasicPermission 所用的语法更为复杂的类都直接是 Permission 的子类,而不是 BasicPermission 的子类。例如,对于 java.io.FilePermission 对象而言,权限名就是文件(或目录)的路径名。 某些权限类具有一个“动作”列表,告知允许对象所执行的动作。例如,对于 java.io.FilePermission 对象, 动作列表(如“读、写”)指定了允许对指定文件(或指定目录中的文件)执行哪些动作。 其他权限类是“指定的”权限 - 有名称但没有动作列表的类;您也许有指定的权限,也许没有。 注:还有一个暗指所有权限的 java.security.AllPermission 权限。该权限是为了简化系统管理员的工作而存在的,因为管理员可能需要执行很多需要所有(或许多)权限的任务。

SecurityManager应用场景:

当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。

启动安全管理器:

参数启动(指定 -Djava.security.manager)通过程序打开SecurityManagerSecurityManager sm =newSecurityManager(); System.setSecurityManager(sm);

关闭安全管理器:

程序关闭:SecurityManager sm =System.getSecurityManager();if(sm !=null){ System.setSecurityManager(null); }
注意:上面的代码只有你在位于${JDK_HOME}/jre/lib/security目录下或者其他指定目录下的java.policy文件中指定了一个权限才会奏效。 这个权限是:
permission java.lang.RuntimePermission "setSecurityManager";

默认配置文件:(默认的安全管理器配置文件是$JAVA_HOME/jre/lib/security/java.policy,即当未指定配置文件时,将会使用该配置。内容如下:)

// Standard extensions get all permissions by default grant codeBase "file:${{java.ext.dirs}}/*" { permission java.security.AllPermission; }; // default permissions granted to all domains grant { // 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 dynamic ports permission java.net.SocketPermission "localhost:0", "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"; };

配置文件简单解释:

配置基本原则:

在启用安全管理器的时候,配置遵循以下基本原则:
没有配置的权限表示没有。只能配置有什么权限,不能配置禁止做什么。同一种权限可多次配置,取并集。统一资源的多种权限可用逗号分割。

默认配置文件解释:

第一部分授权:授权基于路径在"file:${{java.ext.dirs}}/*"的class和jar包,所有权限。
grant codeBase "file:${{java.ext.dirs}}/*" { permission java.security.AllPermission; };
第二部分授权:这是细粒度的授权,对某些资源的操作进行授权。具体不再解释,可以查看javadoc
grant { permission java.lang.RuntimePermission "stopThread"; …… }
补充:当批量配置的时候(例如第一部分授权),有三种模式:
directory/ 表示directory目录下的所有.class文件,不包括.jar文件directory/* 表示directory目录下的所有的.class及.jar文件directory/- 表示directory目录下的所有的.class及.jar文件,包括子目录
可以通过${}来引用系统属性,如:"file:${{java.ext.dirs}}/*"

问题解决:

当出现关于安全管理的报错的时候,基本有两种方式来解决。

取消安全管理器:

一般情况下都是无意启动安全管理器,所以这时候只需要把安全管理器进行关闭,去掉启动参数即可。

增加相应权限:

若因为没有权限报错,则报错信息中会有请求的权限和请求什么权限,如下:
Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission E:\pack\a\a.txt write)
上面例子,请求资源E:\pack\a\a.txt,的FilePermission的写权限没有,因此被拒绝。
也可以开放所有权限:
grant { permission java.security.AllPermission; };