Начиная с Java 7, обновление 45, нельзя больше искать информацию о манифесте, не вызывая предупреждение?

К сожалению, обходной путь, предложенный Oracle и другими здесь ( манифест Java-апплета - Allow all Caller-Allowable-Codebase) для решения проблемы 7 update 45, НЕ работает, если вашему приложению необходим доступ к его загруженным подписанным манифестам jar. В моем случае наше приложение делает это для регистрации соответствующей информации манифеста.

С моим приложением для запуска через Интернет все работало нормально и прекрасно с атрибутом Trusted-Library, который нужно было добавить для 7u21. С 7u45 удаление атрибута "Trusted-Library" и добавление всех дополнительных атрибутов, о которых говорилось в других обходных путях, НЕ будет работать - я получу то же предупреждение, что и вы, если бы вы использовали 7u21 без атрибута Trusted-Library (заявив, что приложение содержит как подписанный, так и неподписанный код):

Я пробовал почти все возможные манифесты /JNLP-перестановки - ничего не режет горчицу.

Я обнаружил, что, в основном, когда мы загружаем один из jar-манипуляций наших апплетов (не jar-файлов JRE) и вызываем hasMoreElements, происходят дополнительные проверки безопасности, которые вызывают предупреждение:

   public List<String> getManifests() {
          ...         

          Enumeration<URL> urls = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");

          while (urls.hasMoreElements()) {
                 .... a bunch of loop stuff
                 // at the end of the loop...
                 System.out.println("Checkpoint SGMLOOP8.");

                 System.out.println("Breaking....");
                 //break; <<<<<<---- if the next jar is one of our signed jars, the next line will trigger the warning. If instead we choose to break, the app works perfectly with no warning.

                 System.out.println("urls.hasMoreElements(): " + (urls.hasMoreElements() ? "true" : "false"));  <<<<<<-------- will evaluate to false if user clicks Block on the warning, otherwise will evaluate to true when our signed jars are next

                 System.out.println("Checkpoint SGMLOOP9."); 
          }
          ...
      }

Вот что распечатывается в консоли Java при максимальной трассировке:

Checkpoint SGMLOOP8.
Breaking....                  <<<<---- console output pauses here until user answers warning
security: resource name "META-INF/MANIFEST.MF" in http://<path_to_jar> : java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://<path_to_jar>
(message repeats for all our signed jars)
urls.hasMoreElements(): false <<<<---- false because user clicked blocked, otherwise true when user clicks don't block
Checkpoint SGMLOOP9.

Мне НАВСЕГДА потребовалось выяснить это, потому что по какой-то причине, когда подписанный манифест, который проходит проверки безопасности ранее в процессе запуска, а затем к нему обращаются и получает жалобы, я, естественно, не думаю, что он жалуется на манифест, а скорее ресурсы, на которые ссылается манифест. Пойди разберись!

Изучая исходный код Java, я понимаю, почему предупреждение может произойти (hasMoreElements приводит к дополнительным проверкам безопасности):

// getResources is called in my code above
java.lang.ClassLoader
public Enumeration<URL> getResources(String name) throws IOException {
    Enumeration[] tmp = new Enumeration[2];
    if (parent != null) {
        tmp[0] = parent.getResources(name);
    } else {
        tmp[0] = getBootstrapResources(name);
    }
    tmp[1] = findResources(name); <<<<------ This returns a new Enumeration<URL> object which has its own “hasMoreElments()” method overwritten – see below code

    return new CompoundEnumeration<>(tmp);
}

java.net.URLClassLoader
public Enumeration<URL> findResources(final String name)
    throws IOException
{
    final Enumeration<URL> e = ucp.findResources(name, true);

    return new Enumeration<URL>() {
        private URL url = null;

        private boolean next() {
            if (url != null) {
                return true;
            }
            do {
                URL u = AccessController.doPrivileged(  <<-- Security context could block this
                    new PrivilegedAction<URL>() {
                        public URL run() {
                            if (!e.hasMoreElements())
                                return null;
                            return e.nextElement();
                        }
                    }, acc);
                if (u == null)
                    break;
                url = ucp.checkURL(u);  <<-- Security checks done in here
            } while (url == null);
            return url != null;
        }

        public URL nextElement() {
            if (!next()) {
                throw new NoSuchElementException();
            }
            URL u = url;
            url = null;
            return u;
        }

        public boolean hasMoreElements() {
            return next();
        }
    };
}

Да, манифесты правильно подписаны! Да, манифесты имеют соответствующие атрибуты! Фактически, это подтверждается тем фактом, что банки загружаются и работают нормально, пока мы не пытаемся получить прямой доступ к их манифестам! Просто чтобы успокоить ваши страхи, вот соответствующие атрибуты манифеста (я пробовал МНОГИЕ дополнения / вычитания атрибутов ниже):

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 24.45-b08 (Oracle Corporation)
Application-Name: AppName
Codebase: *
Permissions: all-permissions
Application-Library-Allowable-Codebase: *
Caller-Allowable-Codebase: *
Trusted-Only: false
Class-Path: jar1.jar jar2.jar jar3.jar
Specification-Title: AppName
Specification-Version: 1.0
Specification-Vendor: CompanyName
Implementation-Title: AppName
Implementation-Version: 1.0
Implementation-Vendor: CompanyName

Вопрос в том, должно ли быть предупреждение, когда мы пытаемся получить доступ к манифестам? В нынешнем виде мы должны либо заставить пользователей видеть предупреждение каждый раз, либо нам нужно удалить нашу регистрацию нашей подписанной информации манифеста jar. Это выглядит как неправильный выбор, тем более что эта информация манифеста очень полезна для устранения неполадок, поскольку это действительно единственный способ убедиться, что конечный пользователь запускает правильную версию приложения (если не считать прямой физической проверки на месте). Это особенно верно в отношении нашего апплета, поскольку в клиентских системах разрешено кэширование jar-файлов (вместе с соответствующим JavaScript для доступа к апплету), что означает, что они могут очень легко запускать неправильные jar-файлы после обновлений / понижений и т. Д. информация в наших журналах может привести к большим головным болям в будущем.

Есть идеи? Это особенно расстраивает, поскольку Oracle все равно намеревается исправить проблему Trusted-Library, поэтому вкладывание всей этой исследовательской работы в это может быть не более чем трата моих выходных. Хмм....

РЕДАКТИРОВАТЬ: Одно наблюдение, которое я имел, было то, что первый jar, который столкнулся с исключением безопасности, на самом деле зависел от другого jar в моем приложении. Я подумал: "Может быть, сначала нужно прочитать манифест зависимой банки?" Поэтому я установил порядок загрузки, чтобы в первую очередь загружались независимые файлы jar. Конечный результат? Я мог видеть, что независимая банка теперь сгенерировала исключение безопасности... и все еще есть предупреждение.

2 ответа

Решение

Требуется обновить этот вопрос, чтобы сказать, что по состоянию на Java 7 Update 55, эта проблема была оказана спорно, так как можно снова поставить как в "Доверенной-библиотеке" и манифест "Caller-Допускаемый-Codebase" атрибуты одновременно. Если оба эти атрибута указаны в манифесте, предупреждение не будет активировано.

Я получаю эту проблему с апплетами и обнаружил, что получаю предупреждение о hasMoreElements в моих собственных файлах.jar апплета (не в системе Java.jars, которые возвращаются первые несколько раз в цикле), и только когда апплет.jar Кэширование файлов включено в Панели управления Java.

Я не могу заставить всех своих клиентов отключить кэширование.jar-файлов, но те, кто это делает, на данный момент счастливы, так как предупреждение о смешанном коде для них не отображается. Это не ответ, в лучшем случае это обходной путь.

Другие вопросы по тегам