2012-03-03 253 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

相关问题