0

ブラウザで実行されるJavajarアプレットを作成し、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の提案を実装しましたが、これはWebブラウザーで機能します(ただし、アプレットビューアーは使用しません)。

私がまだ遭遇しているアプレットビューアでのみ:

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

ブラウザにWebページをロードすると、[信頼/拒否]ダイアログボックスが表示されます。[信頼]をクリックすると、画像が表示されます。

これらは私が取っているステップです:

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ソースコードです(概念を強調するために、余分な例外処理/ nullチェックをすべて削除しました):

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

4 に答える 4

2

デフォルトではアプレットがサンドボックスセキュリティにロードされるため、例外が発生します。サンドボックスでは、アプレットを提供するドメインへのURL接続のみを許可します。つまり、アプレットがgoogleによってホストされていない限り、googleへのURL接続を作成することはできません。

リモートURLに正しく接続するには、次の手順を実行する必要があります。

少なくとも自己署名証明書を作成します。理想的には、ベリサインまたは選択した他の認証局(CA)を介してリンクしている検証済みの証明書があります。証明書の説明

jarsignerを使用してjarに署名します。署名手順

これで、次のようにコードを特権ブロックにラップできます

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を返させました。これは、Webブラウザにロードすると機能します。

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();
    }

  }
}
于 2010-01-06T16:01:17.963 に答える
0

通常のアプリケーションの代わりにアプレットを実行しているようです。アプレットは、ロード元のドメイン外のリソースを取得することはできません。アイデアは、「悪い」アプリケーションが次のようなものを呼び出すのを防ぐことです

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

または、他の種類のデータを不明な宛先に転送します。

本当に外部データを取得する必要がある場合は、アプレットに署名する必要があります。

于 2010-01-06T08:46:31.463 に答える
-1
  1. jarの同じフォルダに「policy.all」というファイルを作成します
  2. 次のテキストをコピーして貼り付けます。

    {パーミッションjava.security.AllPermission;};を付与します。

  3. このようにアプリケーションを起動します:

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

于 2010-01-06T07:22:28.833 に答える
-1

jarコマンドラインから実行されるファイルではなく、ブラウザで実行されるアプレットを作成しようとしているようです。それが本当なら、アプレットはロード元のサーバーにしかアクセスできないため、運が悪いことになります。アプレットから他のサーバーに本当にアクセスしたい場合は、アプレットに署名する必要があります。Googleは、より多くの情報を見つけるお手伝いをします。

于 2010-01-06T07:24:11.207 に答える