熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Tomcat 7 的七大新特性

2013-11-23 20:21:07  來源: Java開源技術 

  Tomcat 引入了許多新功能並對現有功能進行了增強很多文章列出了Tomcat 的新功能但大多數並沒有詳細解釋它們或指出它們的不足或提供代碼示例本文將明確描述Tomcat 中七個最顯著的特征和新增的功能並對其作出評論而不是僅僅列出新的功能本文還提供了代碼例子以方便你可以對其有更好的理解

  本文分為兩個部分分別是Tomcat 的新特性Tomcat 增強的功能

  Tomcat 新特性

   使用隨機數去防止跨站腳本攻擊;

   改變了安全認證中的jessionid的機制防止session攻擊;

   內存洩露的偵測和防止;

   在war文件外使用別名去存儲靜態內容;

  Tomcat 的增強功能

   對Servlet JSP 和JSPEL 的支持;

   更容易將Tomcat內嵌到應用去中去比如JBoss;

   異步日志記

  根據Mark ThomasTomcat 委員會的經理的說法Tomcat 最顯著的三個特征是Servlet 內存檢測洩露和增強的安全特性

  Tomcat 的例子程序中包含了Eclipse的工程文件和Ant的構建文件以方便去構建war文件其中Eclipse工程文件有例子代碼描述了Tomcat 的一些新特性

  下面逐一開始介紹

  Tomcat 新特性

   使用隨機數去防止跨站請求偽造攻擊

  Wikipedia將跨站請求偽造攻擊(Cross Site Request forgeryCSRF)定義為:一種影響Web應用的惡意攻擊CSRF讓用戶當進入一個可信任的網頁時被強行執行惡意代碼

  經典的防止CSRF攻擊的方法是使用隨機數的方式Wikipedia中定義為利用隨機或偽隨機數嵌入到認證協議中以確保舊的不能在以後的重放攻擊中被利用

  Tomcat 中有一個servlet過濾器用於將隨機數存儲在用戶每次請求處理後的seesion會話中這個隨機數必須作為每次請求中的一個參數 Servlet過濾器然後檢查在請求中的這個隨機數是否與存儲在用戶session中的隨機數是一樣的如果它們是相同的該請求是判斷來自指定的網站如果它們是不同的該請求被認為是從其他網站發出並且會被拒絕

  這個servlet過濾器是十分簡單的下面是從Tomcat 源代碼CsrfPreventionFilter文檔中摘錄的片段:

  Java代碼:

  public class CsrfPreventionFilter extends FilterBase {

  public void doFilter(ServletRequest request ServletResponse response

  FilterChain chain) throws IOException ServletException {

  String previousNonce = reqgetParameter(ConstantsCSRF_NONCE_REQUEST_PARAM);

  String expectedNonce = (String) reqgetSession(true)getAttribute(ConstantsCSRF_NONCE_SESSION_ATTR_NAME);

  if (expectedNonce != null && !expectedNonceequals(previousNonce)) {

  ressendError(HttpServletResponseSC_FORBIDDEN);

  return;

  }

  String newNonce = generateNonce();

  reqgetSession(true)setAttribute(ConstantsCSRF_NONCE_SESSION_ATTR_NAME newNonce);

  所以每個URL地址中都有一個從用戶session中提取的隨機數下面是使用的JSTL例子:

  在以前JSTL中構造鏈接可以這樣:

  < c:url var=url value=/show >

  < c:param name=id value= / >

  < /c:url >

  < a href=${show} >Show< /a >

  而現在可以這樣:

  < c:url var=url value=/show >

  < c:param name=id value= / >

  < c:param name=orgapachecatalinafiltersCSRF_NONCE value=${apachecatalinafiltersCSRF_NONCE} / >

  < /c:url >

  具體的例子可以參考Tomcat 自帶例子中的演示這個過濾器可以在webxml中進行配置配置後所有訪問的都必須帶上參數不帶上參數的話會出現禁止訪問錯誤

  當然這種方法的缺點就是所有的鏈接都必須帶上這個隨機數

   改變了安全認證中的jessionid的機制防止session攻擊

  Session劫持攻擊通常是以下的情況:

   惡意攻擊者先訪問一個網頁由於cookie是以jsession id的方式存儲在浏覽器中的即使攻擊者不登陸他可以偽造一個帶有jsession id的地址把它發給受害者

   受害者點這個帶有jsessionid的鏈接提示輸入驗證信息之後就登陸系統;

   攻擊者現在使用這個帶jsessionid的鏈接以受害者的身份登陸進系統了

  對於攻擊者來說將jsessionid加在url中以及通過一個惡意表單發送出去是很容易的事對於session劫持攻擊的更詳細描述請參考Acros Security組織的白皮書Session Fixation Vulnerability in Webbased Applications

  Tomcat 對此的解決方案是一個補丁它在驗證後改變了jsessionid這個補丁主要是應用在Tomcat 當然在Tomcat 中也可以使用但只是有些不同

  根據Mark Thomas說的應用了Tomcat 的這個補丁後:

  Tomcat默認情況下安全性不再變得脆弱因為驗證後會話發生了變化

  如果用戶改變了默認設置(比如應用程序不能處理變化了的session id)風險也會降到最小因為在Servlet 可以禁止在url中進行會話跟蹤

  而在Tomcat 和Tomcat 應用了補丁後:

  能阻止session劫持攻擊因為能讓Tomcat在驗證後改變session id

  如果應用程序不能處理變化了的session id可以通過寫自定義的過濾器去檢查requestisRequestedSessionIdFromURL()和其返回的結果以降低風險

  以上這些改變都是Tomcat在幕後所做的開發者根本不用去理會

   內存洩露的偵測和防止

  開發者在部署他們寫的程序到生產環境上時經常會遇到Pemgen錯誤:OutOfMemoryError這是由於內存洩露而引起的通常開發者是通過增大permgen內存的大小去解決或者就是重新啟動Tomcat

  Tomcat 包含了一個新的特性它通過把不能垃圾回收的引用對象移走的方法能解決一些Permgen內存洩露的問題這個特性對程序員部署應用程序在他們的開發環境中是十分方便的因為程序員在開發環境中為了節省時間一般不重新啟動Tomcat就能部署新的war文件在生產環境中最好的建議還是停掉Tomcat然後清除work下面的目錄文件並且重新部署應用

  當然內存洩露檢測和防止這個特性現在還不是很完善還是有的情況Tomcat不能檢測內存洩露和修復之的所以對於生產環境最好的的辦法還是停掉Tomcat然後清除work下面的目錄文件並且重新部署應用

  Mark Thomas解析應用程序或者庫程序在如下情況下會觸發內存洩露:

  JDBC驅動的注冊

  一些日志框架

  在ThreadLocals中保存了對象但沒有刪除它們

  啟動了線程但沒停止

  而 Java API 存在內存洩漏的地方包括:

  使用 javaximageio API ( Google Web Toolkit會用到)

  使用 javabeansIntrospectorflushCaches()

  使用 XML 解析器

  使用 RMI 遠程方法調用

  從 Jar 文件中讀取資源

   在war文件外使用別名去存儲靜態內容

  Web應用程序需要靜態資源文件比如象CSSJavascript和視頻文件圖片文件等通常都把它們打包放在war文件中這將增加了WAR文件的大小並且導致很多重復的加載靜態資源一個比較好的解決方法是使用Apache HTTP服務器去管理這些靜態文件資源下面是一個apache 文件的配置摘錄:

  < Directory /home/avneet/temp/static >

  Order allowdeny

  Allow from all

  < /Directory >

  Alias /static /home/avneet/temp/static

  以上的設置使得訪問localhost/static時能訪問到放在/home/avneet/temp/static下的資源

  允許使用新的aliases屬性指出靜態文件資源的位置可以通過使用ClassloadergetResourceAsStream(/static/)或者在鏈接中嵌入的方法讓Tomcat去解析絕對路徑下面是一個在contextxml中配置的例子:

  < ?xml version= encoding=UTF? >

  < Context path=/Tomcatdemo aliases=/static=/home/avneet/temp/static >

  < /Context >

  假設/home/avneet/temp/static這個文件夾存放有一張圖片bgpng如果war文件以Tomcatdemo的名字部署那麼可以通過以下三個方式去訪問這張圖片

  直接訪問 localhost:/Tomcatdemo/static/bgpng

  在HTML鏈接中訪問:< img src=/Tomcatdemo/static/bgpng / >

  通過JAVA代碼訪問: ByteArrayInputStream bais = (ByteArrayInputStream)getServletContext()getResourceAsStream(/static/bgpng);

  使用aliases的好處是可以代替Apache的的設置並且可以在servlet容器范圍內訪問並且不需要Apache

  Tomcat 的增強特性

   對Servlet JSP 和JSPEL 的支持

  Servlet 的增強特性有:

  可以在POJO或者過濾器filters中使用annotations注釋(在webxml中不再需要再進行設置了)

  可以將webxml分塊進行管理了也就是說用戶可以編寫多個xml文件而最終在webxml中組裝它們這將大大降低webxml的復雜性增強可讀性比如 strutsjar和springmvcjar每一個都可以有一個webfragmentxml開發者不再需要在webxml中去配置它們了在webfragmentxml中的jar文件會自動加載並且struts/springmvc servlets和filters也會自動裝配設置

  異步處理web的請求這個特性在Tomcat 中已經有了現在在Tomcat 中以Servlet 標准規范化了能讓使用異步I/O的web應用程序可以移植到不同的web容器中異步處理使用非阻塞I/O每次的HTTP連接都不需要對應一個線程更少的線程可以為更多的連接提供服務這對於需要長時間計算處理才能返回結果的情景來說是很有用的比如產生報表Web Servce調用等

  安全的增強Servlet 現在使用SSL 去加強了會話session的跟蹤代替了原來的cookie和URL重寫

   更容易將Tomcat內嵌到應用去中去

  Tomcat 現在可以嵌入到應用程序中去並可以通過程序去動態設置和啟動象在CATALINA_HOME/conf/serverxml中的很多配置現在都可以用程序動態去設置了在Tomcat Tomcat 提供了一個嵌入類它能方便地去配置Tomcat但在Tomcat 這個類已被廢棄了這個新的Tomcat 的類使用了幾個默認的配置元素並提供了一個更容易和簡單的方法去嵌入Tomcat

  下面是CATALINA_HOME/conf/serverxml中的一些相關屬性和配置:

  < Server >

  < Service >

  < Connector port= >

  < Engine >

  < Host appBase=/home/avneet/work/Tomcatdemo/dist / >

  < /Engine >

  < /Connector >

  < /Service >

  < /Server >

  我們可以通過程序去進行動態設置了:

  final String CATALINA_HOME = /home/avneet/work/temp/Tomcatdemo/;

  Tomcat Tomcat = new Tomcat();

  TomcatsetBaseDir( CATALINA_HOME );

  TomcatsetPort( );

  TomcataddWebapp(/Tomcatdemo CATALINA_HOME + /webapps/Tomcatdemowar);

  Tomcatstart();

  Systemoutprintln(Started Tomcat);

  TomcatgetServer()await(); //Keeps Tomcat running until it is shut down

  //Webapp Tomcatdemo accessible at localhost:/Tomcatdemo/

   異步日志記錄

  Tomcat 現在包括了一個異步日志記錄器(AsyncFileHandler)AsyncFileHandler繼承了FileHandler類並能代替FileHandler使用AsyncFileHandler只需要在CATALINA_HOME/conf/loggingproperties中把FileHandler全部替換為AsyncFileHandler就可以了要注意的是異步日志不能跟log一起工作

  當有日志發向AsyncFileHandler時日志被加入到隊列中(ncurrentLinkedBlockingDeque)並且方法調用的信息會馬上返回不需要等待I/O寫到磁盤中當類加載器加載AsyncFileHandler時會有一個單獨的線程啟動這個線程會從隊列中讀取日志信息並且寫到磁盤中去

  這種方法的好處是如果I/O速度很慢(比如日志要保存在遠端的設備上)時記錄日志的請求和處理過程不會顯得很慢

  AsyncFileHandler使用生產者和消費者的關系原理在隊列中存儲日志信息隊列默認大小為為了預防隊列溢出默認是丟棄最後的信息默認的隊列大小和溢出的設置都可以通過啟動參數進行設置

  關於Tomcat 的示例程序

  Tomcat 的自帶程序例子有兩個servlets一個是演示了如何采用隨機數的辦法防止CSRF攻擊另外一個是描述了使用aliases更新一下web/METAINF/contextxml指出圖片的絕對路徑即可順利運行


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28352.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.