Java 为什么servlet通过ApplicationContextFacade(而不是直接)间接访问Tomcat ApplicationContext(ServletContext)
我正在通读Tomcat的源代码,试图找出 tomcat内部受到保护,防止servlet进行未经授权的访问。 我注意到的一件事是,servlet通过ApplicationContextFacade获得对StandardContext的访问,ApplicationContextFacade似乎充当ApplicationContext的代理,而不是允许servlet直接访问ApplicationContext 我想知道为什么ApplicationContextFacade被传递给servlet而不是ApplicationContext。 我怀疑这与安全性有关(因为facade很难简化接口,所以不是典型的facade模式)。 我查看了代码,发现它基本上转发了请求(正如预期的那样),但取决于一些安全设置(例如Globals.IS_security_ENABLED和SecurityUtil.isPackageProtectionEnabled()),它似乎使用java反射来传递请求。 我知道使用反射时权限会发生变化,但我不完全确定这将如何在ApplicationContextFacade中强制执行某些安全策略 如果有人能为我澄清这一点,那就太好了 提前感谢您的帮助 链接到javadoc 链接到tomcat源: 门面代码示例:Java 为什么servlet通过ApplicationContextFacade(而不是直接)间接访问Tomcat ApplicationContext(ServletContext),java,security,tomcat,servlets,reflection,Java,Security,Tomcat,Servlets,Reflection,我正在通读Tomcat的源代码,试图找出 tomcat内部受到保护,防止servlet进行未经授权的访问。 我注意到的一件事是,servlet通过ApplicationContextFacade获得对StandardContext的访问,ApplicationContextFacade似乎充当ApplicationContext的代理,而不是允许servlet直接访问ApplicationContext 我想知道为什么ApplicationContextFacade被传递给servlet而不是A
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);
}
}
最后调用方法
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;
}
}
我认为您还需要访问另一种方法: 我会结合这个答案来看看-
我认为不受信任的代码/类加载器(webapp)可能不允许执行某些操作,因此受信任的代码(Tomcat)可以调用
doPrivileged
,以临时覆盖webapp更受限制的权限。首先感谢您的响应并添加缺少的代码片段!好的,正如我现在看到的,web应用程序代码的访问权限受到安全管理器的限制(例如,无法访问它不是Mime类型的文件),如果没有doprivileged,调用方的有限权限将传播到tomcat,tomcat将无法访问该web应用程序的文件。通过调用doPrivileged,facade实际上会在调用期间覆盖webapp自己(受信任)的访问权限。是这样吗?他们为什么使用反射?我觉得这很正确。我猜他们使用反射将doPrivileged
代码包含到代码库的某个部分,而不是将单个doPrivileged
调用分散在代码库中;这种模式可能更好地让开发人员理解使用这些技巧的地方。这是一个猜测,我不确定。
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 }