Why servlets access Tomcat ApplicationContext (ServletContext) indirectly through ApplicationContextFacade (and not directly)

I read the source code of Tomcat, trying to figure out how tomcat internal elements are protected from unauthorized access from servlets. One thing that I noticed is the fact that servlets access the Context standard through ApplicationContextFacade, which apparently acts as a broker for ApplicationContext rather than allowing servlets to have direct access to ApplicationContext.

I was wondering why ApplicationContextFacade is passed to the servlet and not ApplicationContext. I suspect this has something to do with security (since the facade is unlikely to simplify the interface, so this is not a typical facade template). I looked at the code and saw that it basically redirects requests (as expected), but with certain security settings (such as Globals.IS_SECURITY_ENABLED and SecurityUtil.isPackageProtectionEnabled ()), it seems that java reflection is used to transmit the request. I know that permissions change when using reflection, but I'm not quite sure how this will apply some security policy in ApplicationContextFacade?

It would be great if anyone could clarify this for me!

Thank you in advance for your help.

link to javadoc http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/core/ApplicationContextFacade.html

tomcat source link: http://tomcat.apache.org/download-70.cgi

facade code example:

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

where context is the associated ApplicationContext and doPrivileged is defined as follows:

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

and finally 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; } } 
+3
source share
1 answer

I think you had to visit another method:

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 } 

I would look at this in conjunction with this answer - When should I use AccessController.doPrivileged ()? .

I think that the untrusted code / classloader (webapp) may not have the right to do certain things, so the trusted code (Tomcat) can call doPrivileged to temporarily override webapp privileges with more limited rights.

+2
source

All Articles