JNLP: загрузка неподписанного кода в подписанный код

У нас возникли трудности с преодолением ошибки смешанного кода для Java webstart. Таким образом, у нас есть наш основной файл JNLP, мы подписали весь наш код, который он загружает напрямую. Мы добавили опцию всех разрешений в основной JNLP. Основной класс, который он загружает, также происходит из подписанной банки.

Когда основной класс запускается немного позже, он запускает некоторые вещи, которым необходимо загрузить некоторые неподписанные ресурсы, которые извлекаются из JNLP B. Ни один из ресурсов JNLP B не подписан, и им не нужны какие-либо специальные разрешения.

Весь подписанный код был настроен на основе документации по смешанному коду от Oracle, а файлы jar были установлены с манифестами «Trusted-Library: true» перед подписанием.

Когда неподписанный код пытается загрузиться подписанным кодом, мы получаем ошибку class not found, например:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

    Caused by: java.lang.NoClassDefFoundError: org/some/external/package/that/is/not/signed
at org.our.signed.package.main(Main.java:87)
... 9 more

    Caused by: java.lang.ClassNotFoundException: org.some.external.package.that.is.not.signed
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 10 more

Вот сценарий в JNLP:

JNLP A: (кратко)

<jnlp spec="1.5+" codebase="...." href="......">
  <information>
   ...etc
  </information>
   <security>
     <all-permissions/>
   </security>
   <resources>
      <j2se version="1.6+" initial-heap-size="80m" max-heap-size="256m" href="http://java.sun.com/products/autodl/j2se"/>
      <jar href="signedJar_1.jar" download="eager" main="true"/>
      <jar href="signedJar_2.jar" download="eager" main="false"/>
      <extension name="unsigned_ext" href="unsigned.jnlp"/>
  </resources>
  <application-desc main-class="(FROM SIGNED CLASS in signedJar_1.jar)"/>
</jnlp>

JNLP B (загрузчик unsigned.jnlp)

<jnlp spec="1.5+" codebase="....." href="......">
  <information>
   ...etc
  </information>
  <resources>
    <jar href="unsigned.jar"/>
  </resources>
  <component-desc/>
</jnlp>

Мы отметили, что исключения безопасности работают правильно, потому что, если мы переместим неподписанный jar-файл в JNLP, который имеет все разрешения и имеет подписанные jar-файлы, мы получим ожидаемые исключения безопасности, с которыми Java не позволит нам смешивать подписанный код. Trusted-Library: настоящий и неподписанный код без атрибутов манифеста.

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


person rmmeans    schedule 19.04.2012    source источник


Ответы (1)


Загрузчик классов доверенной библиотеки является родителем (в смысле делегирования загрузчика классов) (возможно, ненадежного) загрузчика классов апплета. Думайте об этом, как если бы это был загрузчик загрузочного класса. Таким образом, ненадежные классы могут ссылаться на классы доверенной библиотеки, но не наоборот. Не утруждая себя изменением манифестов и использованием WebStart, вы можете попробовать это, добавив свой доверенный класс с -Xbootclasspath/a: и ваши ненадежные классы с -classpath (именно так эта функция была опробована до того, как она была реализована).

JNLPAppletLauncher является примером того, как доверенные библиотеки вызывают код апплета. Загрузчик класса апплета можно получить с помощью Thread.currentThread().getContextClassLoader(), и это просто отражение оттуда. Написание безопасного кода доверенной библиотеки — сложная задача. Помните, вы не можете доверять ненадежному коду.

person Tom Hawtin - tackline    schedule 19.04.2012
comment
Так вы говорите, что доверенный код вообще не может запускать ненадежный код? Например, наше приложение — это внутренняя CRM, которая загружается через веб-запуск (без апплетов). Нашей CRM иногда нужен доступ к локальной файловой системе (причина подписи/все пермь). Наша CRM также нуждается в некоторых других jar-файлах, хотя и для других целей, таких как swingx.jar для пользовательского интерфейса, наборы справки, такие как jhall.jar и т. д. Значит, наш доверенный код не может получить доступ к этим другим jar-файлам? Придется ли нам вытаскивать наши доверенные функции в их собственные jar-файлы и подписывать только их, а нашему основному ядру не доверять, чтобы мы также могли использовать недоверенные jar-файлы? - person rmmeans; 20.04.2012
comment
(Applet и приложение/апплет JNLPWebStart по существу взаимозаменяемы.) Вы не можете иметь доверенный код, полагаясь на поведение ненадежного кода. Вы можете иметь доверенный код как библиотеку, но вам нужно быть очень осторожным, чтобы любая операция, выполняемая с ним, была безопасной. Вы не можете просто иметь метод, который, скажем, сохраняет некоторые данные в указанное имя файла (и остается безопасным). - person Tom Hawtin - tackline; 20.04.2012
comment
@ TomHawtin-tackline Если бы код в расширении для песочницы был подписан цифровой подписью, это все равно вызвало бы проблему? - person Andrew Thompson; 20.04.2012
comment
@AndrewThompson Вы имеете в виду, есть ли у вас доверенная библиотека с доверенным апплетом/приложением? С точки зрения загрузки классов это будет вести себя так же, как доверенная библиотека с ненадежным апплетом/приложением. Также, если ему доверяли, но не было <all-permissions/>. / Обратите внимание, что вам действительно нужно отражение только для доступа к первому конструктору/методу/полю. Если это дает объект класса, который расширяет тип в доверенной библиотеке (или библиотеке Java), то дальнейшее взаимодействие может осуществляться через это. - person Tom Hawtin - tackline; 20.04.2012
comment
@ TomHawtin-tackline Я попытался переместить наш основной загрузчик в неподписанный код, удалил все разрешения из основного jnlp и переместил весь доверенный код в его собственные банки с их собственными jnlp и подписал их. У нас все еще есть ошибки, говорящие о том, что наш подписанный код, выполняемый из jnlp с полными разрешениями, не был авторизован. Чтобы решить нашу проблему, мы вернулись к последнему предложению на веб-сайте Oracle подписать все, а затем наши банки, которые являются сторонними, находятся в jnlp, у которых нет модели безопасности для всех разрешений. Теперь он загружается без ошибок, но, вероятно, не идеально. - person rmmeans; 20.04.2012
comment
Вы имеете в виду, есть ли у вас доверенная библиотека?.. Аах! trusted-library совершенно вылетело из моей головы. - person Andrew Thompson; 21.04.2012