Доступ запрещен (соединение java.net.SocketPermission 127.0.0.1:8080, разрешение)
Я вставил Java-апплет на простую HTML-страницу, расположенную по адресу http://localhost:8080/index.html:
<applet id="applet" code="SomeCode.class" archive="lib.jar" Width="1" Height="1"></applet>
У Java-апплета есть метод, который похож на код ниже:
public void PostStuffToServer() {
String server = "http://localhost:8080/PostHandler.ashx";
URL u = new URL(server);
URLConnection con = u.openConnection();
con.setDoOutput(true);
con.getOutputStream().write(stream.toByteArray());
con.connect();
}
Когда я выполняю код апплета из JavaScript примерно так:
obj = document.getElementById('applet');
obj.getClipboardImageURL();
Я получаю следующую ошибку:
доступ запрещен (соединение java.net.SocketPermission 127.0.0.1:8080, разрешение)
Кажется, что код Java разрешает домен localhost к его эквивалентному IP-адресу и, следовательно, повышает междоменное ограничение безопасности. Он отлично работает, когда я выполняю тот же код из http://127.0.0.1:8080/index.html. Файл lib.jar подписан.
Есть ли способ избежать этого?
10 ответов
Я столкнулся с той же проблемой после установки Java 6 Update 22. Мой апплет был в сети в течение нескольких лет без сообщений об ошибках. Когда я понижаю до версии 6, обновление 21, все работает отлично. Мой апплет не подписан.
РЕШЕНИЕ: Мне понадобилось время, чтобы найти причину проблемы. На самом деле в моем случае было несколько факторов, вызывающих ошибку безопасности. Проблема была решена с помощью файла crossdomain.xml. Апплет Java попытался загрузить файл междомена, потерпел неудачу и даже не удосужился отобразить ошибку в консоли Java (уровень отладки 5). Java пыталась загрузить файл с IP-адреса моего домена (http://ip-address/crossdomain.xml), а не из корня моего сайта (http://domain-name/crossdomain.xml). Я полагаю, это лучше с точки зрения безопасности? Затем мне пришлось настроить веб-сервер так, чтобы он представлял кросс-доменный файл по IP-адресу. В моем случае я удалил веб-сайт по умолчанию в ISS по соображениям безопасности, и мне пришлось создать новый веб-сайт. Затем я обнаружил, что Java-апплет не работает с междоменными файлами, которые я использую с flash:
<?xml version="1.0"?>
<cross-domain-policy>
<site-control permitted-cross-domain-policies="master-only"/>
<allow-http-request-headers-from domain="*" headers="*"/>
<allow-access-from domain="*" />
</cross-domain-policy>
Мне пришлось удалить узлы control-site и allow-http-request-headers-from из файла xml, чтобы заставить апплет работать.
Я думаю, что я опоздал, но в любом случае... Ребята, вы не можете поверить, насколько легко решение этой проблемы.
Проблема заключается в том, что код апплета Java, вызываемый из JavaScript, имеет только разрешения, которые являются пересечением кода JavaScript и кода вашего апплета - и каким-то образом разрешения JavaScript рассматриваются как меньшие, что приводит к этому Исключению.
Вот что я сделал: предположим, у вас есть функция innocentFunc()
это вызывает исключение java.net.SocketPermission, поэтому ваш код выглядит примерно так:
String s = innocentFunc();
Теперь вы можете изменить его на что-то вроде этого:
String s = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return innocentFunc();
}
}
);
Этот вызов AccessController в основном сообщает виртуальной машине Java, что код, который она запускает, должен подчиняться не разрешениям из цепочки вызовов, а только разрешениям самого вызывающего.
Конечно, вы должны делать что-то подобное только после того, как убедитесь, что это innocentFunc
call не может сделать ничего плохого, даже если он вызван вредоносным кодом.
Я получаю то же самое с обновлением 22, а не с обновлением 21.
Я использую апплет TinyPlayer, которым я управляю через JavaScript.
Я загружаю аудиофайлы из того же домена (mydomain.example.com, IP 1.2.3.4), что и страница, на которую загружается апплет - на все ссылки ссылаются с помощью относительных URL.
Когда я пытаюсь воспроизвести звук, он не воспроизводится, и я получаю: доступ запрещен (java.net.SocketPermission 1.2.3.4:80 подключение, разрешение)
Просматривая журналы доступа, я получаю запрос на crossdomain.xml прямо перед тем, как это произойдет. Но загвоздка в том, что Java не запрашивает crossdomain.xml у mydomain.example.com/crossdomain.xml ... а вместо 1.2.3.4/crossdomain.xml
Обходное решение, которое мне подходит, - это настроить виртуальный хост, отвечающий за IP-адрес 1.2.3.4, и предоставить ему crossdomain.xml, чтобы Java могла найти crossdomain.xml в (неправильном) месте, ищу это.
Я только что проверил с содержанием:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
... но возможно возможно сделать это более ограничительным.
При этом звук воспроизводится правильно.
Просто добавим, что здесь есть кое-что, что точно соответствует проблеме, с которой я столкнулся, - в частности, упоминается об управлении апплетом с помощью JavaScript.
http://www.oracle.com/technetwork/java/javase/6u22releasenotes-176121.html
Исправление для CVE-2010-3560 могло привести к тому, что некоторые Java-апплеты, работающие в новом Java-плагине, перестали работать, если они встроены в веб-страницы, содержащие JavaScript, который вызывает Java для выполнения действий, требующих разрешений сетевой безопасности. Эти апплеты могут завершиться с ошибкой безопасности сети при некоторых обстоятельствах, если служба имен, которая разрешила исходное имя хоста URL веб-страницы, не возвращает совпадающее имя в результате обратного поиска адреса.
Их предложение состоит в том, чтобы добавить в DNS специальную сумасшедшую запись "просто для Java", например:
10.11.12.13 foo.bar.com.auth.13.12.11.10.in-addr.arpa
У меня была похожая проблема, и она возникает, только когда я использую "localhost" как часть URL-адреса для страницы с апплетом. Когда я использовал URL с реальным именем хоста или IP-адресом как часть URL, проблема не возникла. Я не уверен, что это дефект плагина Java...
Например, когда я использовал URL-адрес, такой как http://localhost:9080/app_id/appletPage проблема, но когда я использовал URL-адрес с использованием фактического IP-адреса или имени хоста, проблема не возникла.
IIRC, политика JavaScript одного и того же происхождения предотвращает доступ к тому же хосту / другому порту. LiveConnect подключаемого модуля применяет эту политику только для локального хоста.
Смотрите: http://download.oracle.com/javase/tutorial/deployment/applet/security.html
Неподписанные апплеты могут выполнять следующие операции:
Они могут устанавливать сетевые подключения к хосту, с которого пришли.
Если Java не преобразует исходную систему в localhost, апплет не сможет открывать сокеты.
Обновление от @Kristian выше спасло мой день.
я имел access denied (java.net.SocketPermission <server_ip>:<server port> connect,resolve)
из апплета в веб-приложении.
В нашем DNS произошли изменения, в результате чего IP-адрес балансировщика нагрузки сервера приложений не преобразовывался в имя с доменом. Поэтому подозреваемое "междоменное соединение" от апплета до сервера было заблокировано. Я добавил crossdomain.xml с
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
в <tomcat-home>/webapps
и проверил, что это доступно с http://<server name>:<server port>/crossdomain.xml
Я не думаю, что возможно сделать файл crossdomain.xml более ограничительным, в настоящее время Java-апплеты поддерживают только (domain="*")
см. здесь http://www.oracle.com/technetwork/java/javase/index-135519.html