Я читал исходный код Tomcat, пытаясь понять, как
внутренние компоненты tomcat защищены от несанкционированного доступа из сервлетов.
Одна вещь, которую я заметил, заключалась в том, что сервлеты получают доступ к StandardContext через ApplicationContextFacade, который, по-видимому, выступает в качестве посредника для ApplicationContext, а не позволяет сервлетам иметь прямой доступ к ApplicationContext.
Мне было интересно, почему ApplicationContextFacade передается сервлету, а не 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);
}
}
и, наконец, вызвать метод
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;
}
}