我正在尝试创建一个将在浏览器中运行的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的建议,它在网络浏览器中 (但不使用applet查看器)。
仅使用applet viewer 我仍然会遇到:
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源代码(为了强调概念,我删除了所有额外的异常处理/ 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;
}
});
}
}
答案 0 :(得分:2)
由于默认applet加载到沙箱安全性,因此您遇到异常,Sandbox只允许您与为applet提供服务的域建立URL连接。这意味着除非您的applet由Google托管,否则您无法创建与Google的网址连接。
您需要执行以下操作才能正确连接到远程网址。
至少创建一个自签名证书,理想情况下,您有一个经过验证的证书,可以通过您选择的verisign或其他证书颁发机构(CA)进行链接。 Certificate Instructions
使用jarsigner签名你的jar。 Signing Instructions
现在您可以将代码包装在特权块中,如下所示
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();
}
}
}
答案 1 :(得分:0)
您似乎正在运行applet而不是正常的应用程序。小程序不允许检索从其加载的域之外的任何资源。这个想法是为了防止“坏”的应用程序调用类似
的东西String targetURL = "http://www.foo.bar/spoof?source" + System.getProperty("...);
或将其他类型的数据传输到未知目的地。
如果您确实需要检索外部数据,则必须签署小程序。
答案 2 :(得分:-1)
复制/粘贴以下文字:
grant {permission java.security.AllPermission;};
启动这样的应用程序:
java -jar yourjar.jar -Djava.security.policy = policy.all
答案 3 :(得分:-1)
听起来你并没有尝试创建一个jar
文件,该文件将从命令行运行,而是一个将在浏览器中执行的applet。如果这是真的,那么你很幸运,因为applet只允许访问他们已经加载的服务器。如果你真的想从applet访问其他服务器,你必须签署你的applet; Google可以帮助您查找更多信息。