исключение безопасности при загрузке веб-изображения в банку - PullRequest
0 голосов
/ 06 января 2010

Я пытаюсь создать java-апплет, который будет запускаться в браузере, загружать изображение с URL-адреса и отображать его для пользователя. Моя реализация:

try {
     String imageURL = "http://www.google.com/intl/en_ALL/images/logo.gif";
     URL url = new URL(imageURL);
     img = ImageIO.read(url);
   } catch (IOException e) {
     System.out.println(e);
   }  

Но это дает мне исключение безопасности:

java.security.AccessControlException: access denied (java.net.SocketPermission www.google.com:80 connect,resolve)

Решение:

Я реализовал предложение Knife-Action-Jesus, и оно работает в веб-браузере (но без использования средства просмотра апплета).

Только при просмотре апплета Я все еще сталкиваюсь:

java.security.AccessControlException: access denied (java.net.SocketPermission www.google.com:80 connect,resolve)

При загрузке веб-страницы в браузере появляется диалоговое окно «Доверие / отказ», если я нажимаю «Доверие», появляется изображение.

Вот шаги, которые я предпринимаю:

ant makejar
jarsigner -keystore keystore-name -storepass password -keypass password web/LoadImageApp.jar alias-name
jarsigner -verify -verbose web/LoadImageApp.jar 
appletviewer web/index.html  ## as mentioned above, this gives a security exception. instead, load the webpage in a browser.

Выходные данные jarsigner -verify:

Warning: The signer certificate will expire within six months.

         332 Thu Jan 07 20:03:38 EST 2010 META-INF/MANIFEST.MF
         391 Thu Jan 07 20:03:38 EST 2010 META-INF/ALIAS-NA.SF
        1108 Thu Jan 07 20:03:38 EST 2010 META-INF/ALIAS-NA.DSA
sm       837 Thu Jan 07 20:03:38 EST 2010 LoadImageApp$1.class
sm       925 Thu Jan 07 20:03:38 EST 2010 LoadImageApp.class
sm        54 Wed Jan 06 01:28:02 EST 2010 client.policy

  s = signature was verified 
  m = entry is listed in manifest
  k = at least one certificate was found in keystore
  i = at least one certificate was found in identity scope

jar verified.

Ниже приведен полный исходный код Java (чтобы подчеркнуть концепцию, я удалил всю эту дополнительную обработку исключений / проверку нуля):

import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;
import java.net.*;
import java.security.*;

public class LoadImageApp extends JApplet
{
  private BufferedImage img;
  private final String imageURL = "http://www.google.com/intl/en_ALL/images/logo.gif";

  public void init()
  {
    loadImage();
  }

  public void paint(Graphics g)
  {
    if (null != img) { g.drawImage(img, 0, 0, null); }
  }

  public void loadImage()
  {
    AccessController.doPrivileged(new PrivilegedAction()
    {
      public Object run()
      {
        try
        {
          URL url = new URL(imageURL);
          if (null == url)
          {
            throw new MalformedURLException();
          }
          img = ImageIO.read(url);
        }
        catch (Exception e) { e.printStackTrace(); }
        return null;
      }
    });
  }

}

Ответы [ 4 ]

2 голосов
/ 06 января 2010

Вы столкнулись с исключением, потому что по умолчанию апплеты загружаются в безопасную среду песочницы, Sandbox позволяет только устанавливать URL-соединения с доменом, обслуживающим апплет. Это означает, что вы не можете создать URL-соединение с Google, если ваш апплет не размещен в Google.

Чтобы правильно подключиться к удаленному URL-адресу, необходимо сделать следующее.

Создайте, по крайней мере, самозаверяющий сертификат. В идеале у вас есть проверенный сертификат, связывающийся через Verisign или какой-либо другой центр сертификации по вашему выбору. Инструкция по сертификации

Подпишите банку с помощью jarsigner. Инструкции по подписанию

Теперь вы можете заключить код в привилегированный блок следующим образом

try 
{
    final String imageURL = "http://www.google.com/intl/en_ALL/images/logo.gif";
    URL url = (URL) AccessController.doPrivileged(new PrivilegedAction() 
    {

        public Object run() 
        {
            try
            {
                return new URL(imageURL);
            }
            catch (MalformedURLException e)
            {
                e.printStackTrace();
                return null;
            }

        }  
    });  

    if(url == null)
    {
         // Something is wrong notify the user
    }
    else
    {
         // We know the url is good so continue on
          img = ImageIO.read(url);
    }

} 
catch (IOException e) 
{
    System.out.println(e);
}  

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

import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;

import java.io.IOException;
import java.net.*;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class LoadImageApp extends Applet
{
  private BufferedImage img;
  private final String imageURL = "http://www.google.com/intl/en_ALL/images/logo.gif";

  public void init()
  {
    loadImage();
  }

  public void paint(Graphics g)
  {
    if (null != img) { g.drawImage(img, 0, 0, null); }
  }

  public void loadImage()
  {
    URL url = (URL) AccessController.doPrivileged(new PrivilegedAction()
    {
      public Object run()
      {
        try
        {
            return new URL(imageURL);
        }
        catch (Exception e) { e.printStackTrace(); }
        return null;
      }
    });

    try {
        img = ImageIO.read(url);
    } catch (IOException e) {
    e.printStackTrace();
    }

  }
}
0 голосов
/ 06 января 2010

Похоже, вы не пытаетесь создать файл jar, который будет запускаться из командной строки, а апплет, который будет выполняться в браузере.Если это правда, вам в значительной степени не повезло, потому что апплетам разрешен только доступ к серверу, с которого они были загружены.Если вы действительно хотите получить доступ к другим серверам из апплета, вы должны подписать свой апплет;Google может помочь вам найти больше информации.

0 голосов
/ 06 января 2010

Кажется, вы запускаете апплет вместо обычного приложения. Апплету запрещено получать какие-либо ресурсы за пределами домена, из которого он был загружен. Идея состоит в том, чтобы не дать «плохим» приложениям вызвать что-то вроде

String targetURL = "http://www.foo.bar/spoof?source" + System.getProperty("...);

или передача других видов данных в неизвестное место назначения.

Если вам действительно нужно извлечь внешние данные, вы должны подписать ваш апплет.

0 голосов
/ 06 января 2010
  1. Создайте файл с именем «policy.all» в той же папке, что и ваш jar
  2. скопируйте / вставьте в него следующий текст:

    предоставить {разрешение java.security.AllPermission;};

  3. Запустите приложение так:

    java -jar yourjar.jar -Djava.security.policy = policy.all

...