2012-03-03 47 views
3

我正在通過Tomcat源代碼閱讀,試圖找出如何防止tomcat內部受到未經授權的servlet訪問。 我注意到的一件事是servlet通過ApplicationContextFacade獲得了對StandardContext的訪問權限,ApplicationContextFacade似乎充當ApplicationContext的代理,而不是允許servlet直接訪問ApplicationContext。爲什麼servlet通過ApplicationContextFacade(而不是直接)間接訪問Tomcat ApplicationContext(ServletContext)

我想知道爲什麼ApplicationContextFacade傳遞給servlet而不是ApplicationContext。 我懷疑這與安全性有關(因爲外觀幾乎不是界面的簡化,所以不是典型的外觀模式)。 我看了看代碼,發現它基本上轉發了請求(如預期的那樣),但是以某些安全設置(例如Globals.IS_SECURITY_ENABLED和SecurityUtil.isPackageProtectionEnabled())爲條件,它似乎使用java反射來傳遞請求。 我知道使用反射時權限會改變,但我不完全確定這將如何在ApplicationContextFacade中強制執行某些安全策略?

如果有人能爲我澄清這一點,這將是偉大的!

非常感謝您的幫助。

連結的Javadoc http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/core/ApplicationContextFacade.html

鏈接到Tomcat源:門面代碼的 http://tomcat.apache.org/download-70.cgi

例如:

public String getMimeType(String file) { 
     if (SecurityUtil.isPackageProtectionEnabled()) { 
      return (String)doPrivileged("getMimeType", new Object[]{file}); 
     } else { 
      return context.getMimeType(file); 
     } 
    } 

其中上下文是相關聯的ApplicationContext對象 和doPrivileged的被定義爲如下:

private Object doPrivileged(final String methodName, final Object[] params){ 
     try{ 
      return invokeMethod(context, methodName, params); 
     }catch(Throwable t){ 
      throw new RuntimeException(t.getMessage(), t); 
     } 
    } 

最後的InvokeMethod

private Object invokeMethod(ApplicationContext appContext, 
           final String methodName, 
           Object[] params) 
     throws Throwable{ 

     try{ 
      Method method = (Method)objectCache.get(methodName); 
      if (method == null){ 
       method = appContext.getClass() 
        .getMethod(methodName, (Class[])classCache.get(methodName)); 
       objectCache.put(methodName, method); 
      } 

      return executeMethod(method,appContext,params); 
     } catch (Exception ex){ 
      handleException(ex, methodName); 
      return null; 
     } finally { 
      params = null; 
     } 
    } 

回答

2

我認爲你需要訪問一個以上方法:

ApplicationContextFacade.executeMethod

468 private Object executeMethod(final Method method, 
469        final ApplicationContext context, 
470        final Object[] params) 
471   throws PrivilegedActionException, 
472    IllegalAccessException, 
473    InvocationTargetException { 
474         
475  if (SecurityUtil.isPackageProtectionEnabled()){ 
476  return AccessController.doPrivileged(new PrivilegedExceptionAction(){ 
477    public Object run() throws IllegalAccessException, InvocationTargetException{ 
478     return method.invoke(context, params); 
479    } 
480   }); 
481  } else { 
482   return method.invoke(context, params); 
483  }   
484 } 

我想看看,在結合這個答案 - When should AccessController.doPrivileged() be used?

我認爲不受信任的代碼/類加載器(webapp)可能不被允許執行某些操作,因此受信任的代碼(Tomcat)可以調用doPrivileged以暫時覆蓋Webapp的更多受限權限。

+0

首先感謝您回覆並添加缺少的代碼片段!好吧,現在我看到了,Web應用程序代碼在安全管理器的訪問權限方面受到限制(例如,無法訪問Mime類型的文件),而沒有使用doprivileged,調用者的有限權限會傳播到tomcat和tomcat將無法訪問該webapp的文件。通過調用doPrivileged,facade實際上會讓webapp在調用期間覆蓋它自己的(受信任的)訪問權限。這是對的嗎?他們爲什麼使用反思? – codelidoo 2012-03-04 14:12:31

+0

這聽起來對我很好。我想他們使用反射來將'doPrivileged'代碼包含到代碼庫的某個部分,而不是在代碼庫中分散單獨的'doPrivileged'調用;這種模式可能會更好地讓開發人員理解這些技巧的使用場所。這是一個猜測,我不知道。 – 2012-03-04 19:23:10

相關問題