我设计了一个Applet来截取屏幕截图并使用java.awt.Robot类将其保存在用户计算机上。我需要将此applet嵌入到html页面中(使用object标签),这样当用户点击网页上的按钮时,就会截取屏幕截图。
小程序本身运行正常,我通过添加临时主方法并在本地计算机上作为常规Java应用程序运行它来测试它。
我遇到困难的是设置权限以允许它从其嵌入位置运行。显然机器人类有点危险,因此需要建立AWTP验证,并且需要对applet本身进行签名。
我在http://download.oracle.com/javase/tutorial/security/toolsign/index.html处完成了教程,并成功创建了一个签名的.jar文件,然后创建了一个允许该教程中的演示应用程序运行的策略文件。我现在遇到的问题是如何协调我学到的东西以及我的applet将用于的情况。
我的目标受众包含大约100台机器,我需要它才能在所有机器上执行。我已将java .class文件打包到.jar中,并使用keytool和jarsigner对其进行签名。然后,我将.jar和.cer文件上传到托管相关页面的服务器目录。
但是:当我使用policytool在其中一台机器上创建新的策略文件来测试设置时,我仍然无法从HTML执行applet。我得到Java.Security.AccessControlException Acess拒绝了java.awt.AWTPermission createRobot错误。
我宁愿怀疑它的政策步骤出错了,所以我将概述我采取的步骤: 我将证书下载到本地计算机并从中生成密钥库,我通过命令行从此目录启动“policytool” 我在本地计算机上添加目录,其中生成密钥库和我的证书。 然后,我点击添加策略按钮并输入SignedBy别名 然后添加权限并选择AWTPermission 目标名称我选择createRobot 函数字段我一直在留空,因为我无法想到这里适用的内容 在此窗口中签名者也留空 然后我点击“确定”和“完成”并收到警告,说明我在第一步输入的别名没有公钥。我执行'另存为'并将我的策略文件保存到与放置证书和从中生成的密钥库相同的目录。
这不允许我从网页上运行applet,但是我对这方面编程的有限理解没有提供出错的线索。
想法,想法,观察?如果我没有明确提到某些东西,那么我还没有做到。我最大的疑问是我收到的警告,但我似乎无法找到它出现的原因
编辑:忘了提一步。我在jre \ lib \ security \ java.security文件中手动添加了'policy.url.3 = file:/ C:/ Testing / debugpolicy'这一行,因为那是我在上述步骤中创建的路径和策略文件名。我刚刚设法删除了我之前提到的警告,我一直在混淆我的别名'并且在创建策略文件期间为私有密钥库而不是公共密钥存储了别名,但是我仍然遇到同样的问题答案 0 :(得分:7)
如果applet签名正确,则不需要策略文件,也不需要单独上传任何证书。正确签名的小程序将在加载小程序时访问小程序时提示用户获得权限。提示符出现了吗?
这是一个小型演示。我写道,演示了Defensive loading of trusted applets。这就是我指的安全提示。
如果applet由开发人员进行数字签名并且最终用户信任,则应该能够进行屏幕截图。
如果小程序可信,您还可以尝试另外一件事,就像实验一样(1)。在小程序init()
的早期,请致电System.setSecurityManager(null)
。这将测试applet是否具有信任,并擦除给予applet的“可信”安全管理器的最后残余。
在可行的情况下,它使屏幕捕获成功,它表明错误或Oracle改变了他们对可信applet可以做的默认值的看法。
1)不要在现实世界或生产环境中这样做。引用Tom Hawtin:
这个问题似乎让人觉得调用
System.setSecurityManager(null);
没问题。 ...如果有人有任何疑问,在applet中更改全局状态将影响同一进程中的所有applet。清除安全管理器将允许任何未签名的applet执行它喜欢的操作。请不要使用您希望任何人信任的证书来签署使用全局州播放的代码。
编辑1: 以下是该演示中使用的简单applet的来源。由于某种原因,当我最初上传它时,我认为来源不相关。由于种种原因,OTOH 3人现在要求查看来源。当我得到一个圆形的tuit时,我会将源上传到我的网站。与此同时,我会把它放在这里。
package org.pscode.eg.docload;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;
import java.security.*;
/** An applet to display documents that are JEditorPane compatible. */
public class DocumentLoader extends JApplet {
JEditorPane document;
@Override
public void init() {
System.out.println("init()");
JPanel main = new JPanel();
main.setLayout( new BorderLayout() );
getContentPane().add(main);
try {
// It might seem odd that a sandboxed applet can /instantiate/
// a File object, but until it goes to do anything with it, the
// JVM considers it 'OK'. Until we go to do anything with a
// 'File' object, it is really just a filename.
File f = new File(".");
// set up the green 'sandboxed page', as a precaution..
URL sandboxed = new URL(getDocumentBase(), "sandbox.html");
document = new JEditorPane(sandboxed);
main.add( new JScrollPane(document), BorderLayout.CENTER );
// Everything above here is possible for a sandboxed applet
// *test* if this applet is sandboxed
final JFileChooser jfc =
new JFileChooser(f); // invokes security check
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
jfc.setMultiSelectionEnabled(false);
JButton button = new JButton("Load Document");
button.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int result = jfc.showOpenDialog(
DocumentLoader.this);
if ( result==JFileChooser.APPROVE_OPTION ) {
File temp = jfc.getSelectedFile();
try {
URL page = temp.toURI().toURL();
document.setPage( page );
} catch(Exception e) {
e.printStackTrace();
}
}
}
} );
main.add( button, BorderLayout.SOUTH );
// the applet is trusted, change to the red 'welcome page'
URL trusted = new URL(getDocumentBase(), "trusted.html");
document.setPage(trusted);
} catch (MalformedURLException murle) {
murle.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (AccessControlException ace) {
ace.printStackTrace();
}
}
@Override
public void start() {
System.out.println("start()");
}
@Override
public void stop() {
System.out.println("stop()");
}
@Override
public void destroy() {
System.out.println("destroy()");
}
}