试想一下,如果你的JSP页面中包含一句代码“System.exit(1);”,你的web应用访问到该JSP时,会发生什么?

一般使用tomcat可能都没有注意到这个问题,本篇主要讲述tomcat 6中SecurityManager的管理机制,尽量使用简单明了的图片表示其中关系。

其他知识参考tomcat文档翻译。如有错误,请予指正。

理解java.policy

  Java是一门安全性很高的语言,因此也会考虑到用户代码对整个系统的侵入性。试想一下,如果你引用了一个jar包,里面包含了依据system.exit(),每次执行到这里都直接退出,会不会很蛋疼!

  Java开发者肯定想过如此的问题,所以引入了java安全策略机制,利用一个配置文件来管理所有的代码权限。

  JDK中就有这样的文件,就是  jre/lib/security/java.policy  ,参考下该文件,就能理解其中的关系:

// 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";
};

  上面给出了基本的权限,例如任何人都可以监听动态端口,以及一些读操作。

  基本过程如下面的图所示:

  用户如果启用了安全管理,即在执行时添加了-Djava.security.manager, 就会在执行某些操作前 先读取 权限文件java.policy,检查是否具体相应权限。

  当然也可以自己定义安全文件,一般有两种方式:

  一种是自己创建SecuirtyManager类,创建一些checkXXX的方法,进行验证;

  另一种就是创建my.policy文件(名字随意),按照规定的语法配置权限,然后启动时添加-Djava.security.manager-Djava.security.policy=xxxx/my.policy参数。

  关于java本身的安全管理不是本篇的重点,下面介绍下tomcat中的安全策略。

理解tomcat中的Security

  Tomcat中的安全管理原理基本与前面JDK中的security类似,只是启动时需要在start后面添加-security参数,tomcat会自动读取 conf/catalina.policy 文件中的权限配置。启动命令如下:

F:apache-tomcat-xxx/bin/startup.bat -security

  catalina.policy中默认已经配置了很多的安全策略,这里就不多说明了,下个部分会针对某一特定文件进行说明:

// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License. // ============================================================================
// catalina.policy - Security Policy Permissions for Tomcat 6
//
// This file contains a default set of security policies to be enforced (by the
// JVM) when Catalina is executed with the "-security" option. In addition
// to the permissions granted here, the following additional permissions are
// granted to the codebase specific to each web application:
//
// * Read access to its document root directory
// * Read, write and delete access to its working directory
// ============================================================================ // ========== SYSTEM CODE PERMISSIONS ========================================= // These permissions apply to javac
grant codeBase "file:${java.home}/lib/-" {
permission java.security.AllPermission;
}; // These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
permission java.security.AllPermission;
}; // These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/../lib/-" {
permission java.security.AllPermission;
}; // These permissions apply to all shared system extensions when
// ${java.home} points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/lib/ext/-" {
permission java.security.AllPermission;
}; // ========== CATALINA CODE PERMISSIONS ======================================= // These permissions apply to the daemon code
grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
permission java.security.AllPermission;
}; // These permissions apply to the logging API
// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home},
// update this section accordingly.
// grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..}
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
permission java.io.FilePermission
"${java.home}${file.separator}lib${file.separator}logging.properties", "read"; permission java.io.FilePermission
"${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
permission java.io.FilePermission
"${catalina.base}${file.separator}logs", "read, write";
permission java.io.FilePermission
"${catalina.base}${file.separator}logs${file.separator}*", "read, write"; permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader"; permission java.util.logging.LoggingPermission "control"; permission java.util.PropertyPermission "java.util.logging.config.class", "read";
permission java.util.PropertyPermission "java.util.logging.config.file", "read";
permission java.util.PropertyPermission "catalina.base", "read"; // Note: To enable per context logging configuration, permit read access to
// the appropriate file. Be sure that the logging configuration is
// secure before enabling such access.
// E.g. for the examples web application (uncomment and unwrap
// the following to be on a single line):
// permission java.io.FilePermission "${catalina.base}${file.separator}
// webapps${file.separator}examples${file.separator}WEB-INF
// ${file.separator}classes${file.separator}logging.properties", "read";
}; // These permissions apply to the server startup code
grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
permission java.security.AllPermission;
}; // These permissions apply to the servlet API classes
// and those that are shared across all class loaders
// located in the "lib" directory
grant codeBase "file:${catalina.home}/lib/-" {
permission java.security.AllPermission;
}; // If using a per instance lib directory, i.e. ${catalina.base}/lib,
// then the following permission will need to be uncommented
// grant codeBase "file:${catalina.base}/lib/-" {
// permission java.security.AllPermission;
// }; // ========== WEB APPLICATION PERMISSIONS ===================================== // These permissions are granted by default to all web applications
// In addition, a web application will be given a read FilePermission
// and JndiPermission for all files and directories in its document root.
grant {
// Required for JNDI lookup of named JDBC DataSource's and
// javamail named MimePart DataSource used to send mail
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "java.naming.*", "read";
permission java.util.PropertyPermission "javax.sql.*", "read"; // OS Specific properties to allow read access
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"; // JVM properties to allow read access
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 "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"; // Required for OpenJMX
permission java.lang.RuntimePermission "getAttribute"; // Allow read of JAXP compliant XML parser debug
permission java.util.PropertyPermission "jaxp.debug", "read"; // Precompiled JSPs need access to these packages.
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*"; // Precompiled JSPs need access to these system properties.
permission java.util.PropertyPermission
"org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
permission java.util.PropertyPermission "org.apache.el.parser.COERCE_TO_ZERO", "read";
}; // The Manager application needs access to the following packages to support the
// session display functionality. These settings support the following
// configurations:
// - default CATALINA_HOME == CATALINA_BASE
// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE
// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME
grant codeBase "file:${catalina.base}/webapps/manager/-" {
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
};
grant codeBase "file:${catalina.home}/webapps/manager/-" {
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
}; // You can assign additional permissions to particular web applications by
// adding additional "grant" entries here, based on the code base for that
// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
//
// Different permissions can be granted to JSP pages, classes loaded from
// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
//
// For instance, assume that the standard "examples" application
// included a JDBC driver that needed to establish a network connection to the
// corresponding database and used the scrape taglib to get the weather from
// the NOAA web server. You might create a "grant" entries like this:
//
// The permissions granted to the context root directory apply to JSP pages.
// grant codeBase "file:${catalina.base}/webapps/examples/-" {
// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };
//
// The permissions granted to the context WEB-INF/classes directory
// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" {
// };
//
// The permission granted to your JDBC driver
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
// };
// The permission granted to the scrape taglib
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };

  这里需要注意的是其配置语法:

grant [signedBy <signer>,] [codeBase <code source>] {
permission <class> [<name> [, <action list>]];
};

  都要按照上面的格式进行配置。其中:

  codeBase 是通过URL的方式指定文件,可以使用变量${java.home}或者${catalina.home}来表示JDK和tomcat的根目录。

  class 指定了相应的操作

  [name,[,action]] name指定具体的操作或者文件,action指定可选的动作(比如read write等等)。

  具体的配置样例,可以参考上面的默认文件。

  

  另外要说明的就是都可以配置哪些操作,也就是permission后面都可以跟哪些类,他们的作用都是什么?

  上面列表中,最常用的java.io.FilePermission用于文件的操作、java.lang.RuntimePermission(可以通过禁用该权限达到防止system.exit(1)的目的)等等。

Security配置实战

  在tomcat中配置security,可以按照下面几个步骤:

  1 在样例代码中执行特殊权限操作:

<%@ page language="java" contentType="text/html; charset=utf-8"
import="java.net.*,java.io.*"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>security Test</title>
</head>
<body>
<h1>security Test</h1>
<hr>
<%!
String txt2String(File file){
String result = "";
try{
BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
String s = null;
while((s = br.readLine())!=null){//使用readLine方法,一次读一行
result = result + "\n" +s;
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
return result;
}
%>
<%
//是否启用了security,如果没有启用会输入null。
System.out.println("SecurityManager: " + System.getSecurityManager());
File file = new File("C:/Users/Administrator/Desktop/test.txt");
//执行文件读操作,即java.io.FilePermission
System.out.println(txt2String(file));
//执行获取文件属性操作,即java.util.PropertyPermission
System.out.println(System.getProperty("file.encoding"));
%>
</body>
</html>

  当访问该页面时,会自动执行下面的代码,如果不具有相应的权限,会直接报错:

    //执行文件读操作,即java.io.FilePermission
System.out.println(txt2String(file));
//执行获取文件属性操作,即java.util.PropertyPermission
System.out.println(System.getProperty("file.encoding"));

  2 配置安全策略文件catalina.policy:

  只需要在catalina.policy末尾添加如下的配置即可:

grant {
permission java.io.FilePermission "C:/Users/Administrator/Desktop/test.txt", "read";
permission java.util.PropertyPermission "file.encoding", "read";
};

  3 在命令行中添加-security启动

  访问JSP执行代码,样例中访问 http://localhost:8080/JSPTest/securityTest.jsp

  可以看到控制台正常输出:

  对比下正常启动的输出,SecurityManager会输出null(此时,如果JSP中有system.exit(1);程序就会直接退出):

  如果没有配置读写文件的权限,会报错(注释掉安全配置的第一句):

grant {
//permission java.io.FilePermission "C:/Users/Administrator/Desktop/test.txt", "read";
permission java.util.PropertyPermission "file.encoding", "read";
};

  如果没有配置获取文件属性权限,则会报错:

grant {
permission java.io.FilePermission "C:/Users/Administrator/Desktop/test.txt", "read";
//permission java.util.PropertyPermission "file.encoding", "read";
};

  因此,如果在安全管理模式下,进行了越权的操作,就会报错有的甚至直接导致程序退出。

  通过报错信息,可以快速的知道缺乏什么权限,根绝该报错就可以方便的配置安全策略。

参考

【1】Java.security.policy文件:http://www.tmser.com/post-187.html

【2】Java安全管理器:http://bubuko.com/infodetail-306759.html

【3】tomcat 6.0 security manager:http://tomcat.apache.org/tomcat-6.0-doc/security-manager-howto.html

Tomcat 6 --- 你很少使用的安全管理SecurityManager的更多相关文章

  1. Tomcat你很少使用的安全管理SecurityManager

    试想一下,如果你的JSP页面中包含一句代码“System.exit(1);”,你的web应用访问到该JSP时,会发生什么? 一般使用tomcat可能都没有注意到这个问题,本篇主要讲述tomcat 6中 ...

  2. 11 个很少人知道但很有用的 Linux 命令

    Linux命令行吸引了大多数Linux爱好者.一个正常的Linux用户一般掌握大约50-60个命令来处理每日的任务.Linux命令和它们的转换对于Linux用户.Shell脚本程序员和管理员来说是最有 ...

  3. myeclipse配置下tomcat debug启动很无比慢

    myeclipse配置下tomcat debug启动很无比慢,而run启动很快今天照常使用MyEclipse 6.5 Blue Edition进行开发,但是却遇到一个怪问题.在MyEclipse环境下 ...

  4. linux下snprintf和sprinf很少被提及的区别

    函数原型:int snprintf(char *dest, size_t size, const char *fmt, ...);函数说明: snprintf函数中的第二个参数,size的解释:siz ...

  5. 很少人知道的office专用卸载工具

    Microsoft Office是微软公司开发的一套基于 Windows 操作系统的办公软件套装.常用组件有 Word.Excel.Powerpoint等.当我们不需要再用了或者想安装旧版本的话,首先 ...

  6. DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)

    函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...

  7. Unix / 类 Unix shell 中有哪些很酷很冷门很少用很有用的命令?(转)

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:孙立伟 链接:http://www.zhihu.com/question/20140085/answer/14107336 ...

  8. 12个很少被人知道的CSS事实

    之前没有认真的研究过,padding-bottom的值如果是百分比,那么它的实际值是根据父类的宽度来调整的.我还以为是根据这个元素的本身的宽度来定义呢?汗..padding-top/padding-l ...

  9. 为什么国外的 App 很少会有开屏广告?

    前言: 笔者在知乎看到这个问题,觉得这的确是一个值得关注和回答的现象,遂写了回答并整理成本文发布在此抛砖引玉,欢迎讨论. 正文: 古话说得好,先问是不是,再问为什么. 对于「国外的 App 很少有开屏 ...

随机推荐

  1. hdu 3089 约瑟夫环

    原来并不知道约瑟夫环还可以递推直接解orz 约瑟夫问题的递推公式: 设f[n]表示一共n个人,数到k出局,这样最后的winner (n个人从0开始标号,即0--n-1) f[n]=(f[n-1]+k) ...

  2. Allegro笔记三

    1.设置Gerber导出目录 可以在$Install_Dir/share/pcb/text/env.txt目录里面添加:“set artpath = . ../Gerber/”语句. 其他各种文件夹设 ...

  3. 深入学习 memset 函数

    最近,和同学讨论了一下memset函数,趁着周五空闲做一总结. memset函数最常用的功能就是初始化数组了(主要是置零),如 #include <iostream> #include & ...

  4. Objective-C 中基于RunTime实现的反射

    一.反射 反射,一般表现在字符串和Class转换,字符串和内部方法转换,字符串和属性的转换(取值和赋值). 二.Objective-C中的反射 OC的反射是基于其Runtime实现的. 以执行某个函数 ...

  5. 【Alpha阶段】第二次Scrum例会

    燃尽图软件存在bug,正在排查修复:(已修复)由于时区设置到了美国,图表显示有问题. 会议信息 时间:2016.10.18 22:00 时长:1h 地点:大运村1号公寓5楼楼道 类型:设计阶段阶段性会 ...

  6. Linux添加新盘扩容空间

    添加磁盘扩容操作:1.添加物理磁盘到服务器重启服务器,#fdisk -l查看识别磁盘(以/dev/sdb为例)[ ~]# fdisk -lDisk /dev/sda: 42.9 GB, 4294967 ...

  7. 真机调试之android手机+chrome

    真机调试之android手机+chrome 虽然chrome上的移动设备模拟器很强大,但是在真机运行的时候,总会遇到一些小问题,这时就需要使用真机调试了. 第一步:准备一台android手机,并在手机 ...

  8. UINT数相减

    UINT32 i = ; UINT32 j = ; i - j > //这个将永远为真,因为他是将将结果按照无符号解析 int = i -j; //这个是-1,是按照有符号解析 今天发现代码里面 ...

  9. Zipf定律

    http://www.360doc.com/content/10/0811/00/84590_45147637.shtml 英美在互联网具有绝对霸权 Zipf定律是美国学者G.K.齐普夫提出的.可以表 ...

  10. Java关键字——static

    static申明属性 如果有属性希望被所有对象共享,则必须将其申明为static属性. 使用static声明属性,则此属性称为全局属性,有时候也称为静态属性. 当一个类的属性申明位static的时候, ...