zoukankan      html  css  js  c++  java
  • Tomcat你很少使用的安全管理SecurityManager

    试想一下,如果你的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或者 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 + "
    " +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
  • 相关阅读:
    环境是如何建立的 启动文件有什么
    环境中存储的是什么
    串行 并行 异步 同步
    TPC-H is a Decision Support Benchmark
    进程通信类型 管道是Linux支持的最初Unix IPC形式之一 命名管道 匿名管道
    删除环境变量
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.2 autocommit, Commit, and Rollback 自动提交 提交和回滚
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
    14.3.2.1 Transaction Isolation Levels 事务隔离级别
  • 原文地址:https://www.cnblogs.com/firstdream/p/8392900.html
Copyright © 2011-2022 走看看