簡體   English   中英

在jar中加載Web圖像時的安全異常

[英]security exception when loading web image in jar

我試圖創建一個將在瀏覽器中運行的Java jar Applet,從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瀏覽器中使用(但不能使用applet查看器)。

僅使用applet查看器,我仍然會遇到:

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

}

遇到異常是因為默認情況下,小程序會加載到沙箱安全性中,因此,沙箱僅允許您與服務小程序的域建立url連接。 這意味着除非您的applet由google托管,否則您無法創建與google的url連接。

您需要執行以下操作才能正確連接到遠程URL。

至少創建一個自簽名證書,理想情況下,您具有通過verisign或您選擇的其他證書頒發機構(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);
}  

我導入了您的applet代碼,並進行了一些切換,將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();
    }

  }
}

看來您正在運行的是applet,而不是普通的應用程序。 小程序不允許從其加載的域中檢索任何資源。 這個想法是為了防止“不良”應用程序調用類似

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

或將其他類型的數據傳輸到未知目的地。

your applet. 如果確實需要檢索外部數據,則必須對小程序

  1. 在jar的同一文件夾中創建一個名為“ policy.all”的文件
  2. 復制/粘貼以下文本:

    授予{權限java.security.AllPermission;};

  3. 像這樣啟動應用程序:

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

聽起來好像您不是要創建將通過命令行運行的jar文件,而是要在瀏覽器中執行的applet。 如果是這樣,那么您將很不走運,因為小應用程序僅被允許訪問從中加載它們的服務器。 如果您確實要從小程序訪問其他服務器,則必須對小程序進行簽名; Google可以幫助您找到更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM