【Java 安全技术探索之路系列:J2SE安全架构】之二:安全管理器

作者:郭嘉 邮箱:allenwells@163.com 博客: github:https://github.com/AllenWell

一 安全管理器的功能

安全管理器是一个允许程序实现安全策略的类,它会在运行阶段检查需要保护的资源的访问权限及其它规定的操作权限,保护系统免受恶意操作攻击,以达到系统的安全策略。

安全管理器负责检查的操作主要包括以下几个:

注意:在运行Java应用程序时,默认的设置是不安装安全管理器的,这样所有的操作都是允许的,

安全管理器的工作流程如下图所示:

一 安全管理器的使用1.1 获取安全管理器Security security = System.getSecurityManager();1.2 启动安全管理器1.2.1 命令行启动java -Djava.security.manager class_name1.2.2 程序启动

在启动安全管理器时可以通过-Djava.security.policy选项来指定安全策略文件。如果没有指定策略文件的路径,那么安全管理器将使用默认的安全策略文件,它位于%JAVA_HOME%/jre/lib/security目录下面的java.policy。

注意:

=表示这个策略文件将和默认的策略文件一同发挥作用。==表示只使用这个策略文件。

policy文件包含了多个grant语句,每一个grant描述某些代码拥有某些操作的权限。在启动安全管理器时会根据policy文件生成一个Policy对象,任何时候一个应用程序只能有一个Policy对象。

SecurityManager sm=new SecurityManager();System.setSecurityManager(sm);

默认的%JAVA_HOME%/jre/lib/security/java.policy文件内容如下所示:

// Standard extensions get all permissions by defaultgrant codeBase “file:${{java.ext.dirs}}/*” {permission java};// default permissions granted to all domainsgrant {// Allows any thread to stop itself using the java()// 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() for more// information.permission java// allows anyone to listen on dynamic portspermission java, “listen”;// “standard” properies that can be read by anyonepermission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;permission java, “read”;};1.3 关闭安全管理器SecurityManager sm=System.getSecurityManager();if(sm!=null){System.setSecurityManager(null);}

以上代码只有在位于{JDK_HOME}/jre/lib/security目录下或者其他指定目录下的java.policy文件中指定了一个权限才会生效。

该权限是:

permission java1.4 安全管理器检查security.checkXXX(…);

检查完成后,成功则安全管理器返回,失败则安全管理器抛出SecurityException,注意该约定唯一的例外是checkTopLevelWindow,它返回boolean值。

1.5 安全管理器权限检查

安全管理器中所有其他check()方法的默认实现都是调用SecurityManager.checkPermission()方法来确定线程是否具有执行所请求的操作的权限。

只带有单个权限参数的checkPermission()方法总是在当前执行的线程上下文中执行安全检查。

如果在给定的上下文进行检查需要在不同的上下文中进行,可以使用Java提供的包含上下文参数的getSecurityContext()方法和checkPermission()方法,如下所示:

Object context = null;SecurityManager sm = System.getSecurityManager();if(sm != null){context = sm.getSecurityContext();//该方法返回当前调用上下文的一个快照sm.checkPermission(permission, context);//该方法使用一个上下文对象,以及根据该上下文(不是当前执行线程的上下文)作出访问决策的权限。}

权限分为以下几个类别:

对应的权限类为:

整个权限类的层次结构如下图所示:

下面写一个例子来演示一下自定义安全管理器的使用。

import java.io.FileInputStream;import java.io.FileNotFoundException;{(String[] args) throws FileNotFoundException{System.out.println(“SecurityManager: ” + System.getSecurityManager());FileInputStream fis = new FileInputStream(“C:\\Users\\Administrator\\my.txt”);System.out.println(System.getProperty(“file.encoding”));}}

注意:my.txt是已经存在的文件,需要在你的目录创建,这里的目录是C:\Users\Administrator。

直接运行

直接运行SecurityManagerDemo,相当于没有启动安全管理器,SecurityManager打印出来为null,且能正确读取protect.txt文件跟file.encoding属性。如下图所示:

添加启动参数运行

添加启动参数

-Djava=C:\\Users\\Administrator\\my.policy//自定义策略文件

指定-Djava.security.manager参数,此时SecurityManager打印出来为不为null,my.policy里面并没有做任何授权,所以在读取文件的时就抛出AccessControlException异常,如下图所示:

创建my.policy,并写入以下grant:

grant {permission java, “read”;permission java, “read”;};

此时可以正确读取,如下图所示:

三 实现自定义的安全管理器

实现自定义的安全管理器一般分为两步:

创建一个SecurityManager子类,根据需要重写一些方法。根据应用程序代码的权限需要配置策略文件。

下面写一个例子来演示一下自定义安全管理器的使用:

你可以选择这样的“三心二意”:信心恒心决心;创意乐意。

【Java 安全技术探索之路系列:J2SE安全架构】之二:安全管理器

相关文章:

你感兴趣的文章:

标签云: