Почему сервлеты обращаются к Tomcat ApplicationContext (ServletContext) косвенно через ApplicationContextFacade (а не напрямую) - PullRequest
3 голосов
/ 04 марта 2012

Я читал исходный код 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;
        }
    }

1 Ответ

2 голосов
/ 04 марта 2012

Я думаю, вам нужно было посетить еще один метод:

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 }

Я хотел бы взглянуть на это в сочетании с этим ответом - Когда следует использовать AccessController.doPrivileged ()? .

Я думаю, что недоверенному коду / загрузчику классов (веб-приложению) может быть запрещено делать определенные вещи, поэтому доверенный код (Tomcat)) может вызвать doPrivileged для временного переопределения более ограниченных привилегий веб-приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...