1. 程式人生 > >Tomcat 6 --- 你很少使用的安全管理SecurityManager

Tomcat 6 --- 你很少使用的安全管理SecurityManager

can 作用 開發 see 方法 encoding txt ava 以及

試想一下,如果你的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中默認已經配置了很多的安全策略,這裏就不多說明了,下個部分會針對某一特定文件進行說明:

技術分享View Code

  這裏需要註意的是其配置語法:

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 在樣例代碼中執行特殊權限操作:

技術分享View Code

  當訪問該頁面時,會自動執行下面的代碼,如果不具有相應的權限,會直接報錯:

    //執行文件讀操作,即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

http://www.cnblogs.com/xing901022/p/4565730.html

Tomcat 6 --- 你很少使用的安全管理SecurityManager