- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在通读 Tomcat 源代码,试图弄清楚如何tomcat 的内部结构受到保护,防止来自 servlet 的未授权访问。我注意到的一件事是 servlet 通过 ApplicationContextFacade 获得对 StandardContext 的访问,这似乎充当 ApplicationContext 的代理,而不是允许 servlet 直接访问 ApplicationContext。
我想知道为什么将 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);
}
}
其中 context 是关联的 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;
}
}
最佳答案
我认为您需要再访问一种方法:
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的更多限制权限。
关于java - 为什么servlets通过ApplicationContextFacade间接访问Tomcat的ApplicationContext(ServletContext)(而不是直接访问),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9550804/
我是一名优秀的程序员,十分优秀!