如何从 Applet 中模拟模式对话框?
在 setVisible(true) 上,我调用以下代码来启动模式对话框:
private synchronized void startModal () {
try {
if (SwingUtilities.isEventDispatchThread()) {
EventQueue theQueue = getToolkit().getSystemEventQueue();
while (isVisible()) {
AWTEvent event = theQueue.getNextEvent();
Object source = event.getSource();
if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch();
} else if (source instanceof Component) {
((Component) source).dispatchEvent(event);
} else if (source instanceof MenuComponent) {
((MenuComponent) source).dispatchEvent(event);
} else {
System.err.println("Unable to dispatch: " + event);
}
}
} else {
while (isVisible()) {
wait();
}
}
} catch (InterruptedException ignored) { }
}
这在大多数浏览器中都非常有效。 然而,在 Windows 版 Opera 和 Safari 中,我遇到了以下令人讨厌的异常:
java.security.AccessControlException: access denied (java.awt.AWTPermission accessEventQueue)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkAwtEventQueueAccess(Unknown Source)
at java.awt.Toolkit.getSystemEventQueue(Unknown Source)
是否有解决方法可以在这些浏览器中生成假模态对话框?
On setVisible(true), I call the following code to start a modal dialog:
private synchronized void startModal () {
try {
if (SwingUtilities.isEventDispatchThread()) {
EventQueue theQueue = getToolkit().getSystemEventQueue();
while (isVisible()) {
AWTEvent event = theQueue.getNextEvent();
Object source = event.getSource();
if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch();
} else if (source instanceof Component) {
((Component) source).dispatchEvent(event);
} else if (source instanceof MenuComponent) {
((MenuComponent) source).dispatchEvent(event);
} else {
System.err.println("Unable to dispatch: " + event);
}
}
} else {
while (isVisible()) {
wait();
}
}
} catch (InterruptedException ignored) { }
}
This works just great in most browsers. However, in Opera and Safari for Windows, I am confronted with the following big-nasty-exception:
java.security.AccessControlException: access denied (java.awt.AWTPermission accessEventQueue)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkAwtEventQueueAccess(Unknown Source)
at java.awt.Toolkit.getSystemEventQueue(Unknown Source)
Is there a workaround for generating fake-modal dialogs in these browsers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除非您有一个奇怪的实现,否则应该授予该权限(Sun PlugIn 自 1.2.2 起就已授予该权限,IIRC)。 我们正在谈论哪些版本?
这可能不是最好的调度循环。
您可能应该在 EDT 中调用
isVisible
。模态界面通常都很糟糕。
模式对话框有什么问题?
That permission should be granted unless you have a strange implementation (Sun PlugIn has been granting it since 1.2.2, IIRC). Which versions are we talking about?
That probably isn't the best dispatch loop.
You probably should call
isVisible
off the EDT.Modal interfaces are generally nasty.
What's wrong with a modal dialog?
如果我可以提供一种可行的不同方法,而不是拦截事件线程中的事件, 您可以使用玻璃窗格来阻止所有输入请求。
If I might offer a different approach that could work, instead of intercepting the events in the event thread, you could use the glass pane to block all input requests.
您不需要签署您的小程序才能使其正常工作吗?
对小程序进行签名
允许小程序执行所有这些操作的方法是对其进行数字签名。 实际上,签名者说“这个小程序可以安全使用,如果你信任我,你就可以信任这个小程序,因为通过我的签名,你可以放心,自从我签名以来它没有被篡改过。” 然后,用户将被询问是否要信任签名者(通常在一个小对话框中),如果她愿意,小程序就可以以完全权限继续进行。 如果信任被拒绝,小程序将继续以有限的权限在沙箱内运行。
应该非常明智地做出是否信任小程序的决定,因为受信任的小程序具有与本地启动的应用程序相同的特权:它可以读取和删除文件,并通过网络传输数据。
关于小程序安全模型的更全面的解释可以在这里找到。 其中包括小程序限制的完整列表。
有关小程序签名的介绍和更多信息的链接,请阅读此内容,尤其是此内容。 Internet Explorer(和 MS JVM)有点不标准; 阅读本文以了解要做什么的概述。
如果即使在签署小程序后,您仍然收到 SecurityException,请尝试将代码作为特权代码运行:
AccessController.doPrivileged(new PrivilegedAction() {
公共对象运行(){
// 此处执行安全敏感操作
返回空值;
}
});
JavaDoc:java.security.AccessController
策略文件
授予 applet 附加功能的另一种方法是使用策略文件,Sun 有一篇介绍性文章,这里还有一篇专门针对 applet 的文章。 使用策略可以以更细粒度的方式控制授予小程序的权限。 例如,可以授予小程序访问本地文件系统的权限,但不能授予它们被拒绝的任何其他功能。 这是一个例子。
使用策略文件的缺点是它们驻留在本地文件系统上,因此用户必须对通常不在他们视线范围内的文件进行更改,并且其内容很难理解。
以下示例显示如何撤销大多数小程序限制。 任何权限都可以变得更加具体,例如,可以仅为选定的文件授予 FilePermission,并且具有只读访问权限。 每个 Permission 类的 javadoc 详细解释了可能的情况。 最好使用尽可能受限制的设置。 RuntimePermission 特别可用于创建 ClassLoaders 和 SecurityManager,这可以规避更多小程序限制。
Javadocs
JavaDoc:java.awt.AWTPermission
JavaDoc:java.io.FilePermission
JavaDoc:java.lang.RuntimePermission
JavaDoc:java.net.SocketPermission
JavaDoc:java.util.PropertyPermission
Don't you need to sign your applet in order this to work?
Signing an applet
The way to allow an applet to do all those things is to digitally sign it. In effect the signer says "This applet is safe to use, and if you trust me, you can trust this applet, because through my signature you can be assured that it has not been tampered with since I signed it." The user will then be asked if she wants to trust the signer (usually in a little dialog box), and if she does, the applet can proceed with full privileges. If the trust is denied, the applet continues to run inside the sandbox with limited privileges.
The decision of whether to trust an applet should be made very judiciously, because a trusted applet has the same privileges a locally started application would have: It can read and delete files, and transmit data over the network.
A more thorough explanation of the applet security model can be found here. That includes a full list of the applet restrictions.
For an introduction to applet signing and links to more information read this and especially this. Internet Explorer (and the MS JVM) are a bit non-standard; read this for an overview of what to do.
If, even after signing the applet, you still get a SecurityException, try running the code as privileged code:
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// perform the security-sensitive operation here
return null;
}
});
JavaDoc:java.security.AccessController
Policy files
An alternative way to grant an applet additional capabilities is the use of Policy files, about which Sun has an introductory article, and another one here specifically for applets. Using policies it is possible to control in a more fine-grained way which privileges to grant an applet. E.g., it becomes possible to grant applets access to the local file system, but not any of the other capabilities they are denied. Here is an example of that.
The drawback to using policy files is that they reside on the local file system, so users must make changes to a file that is normally out of their sight, and the contents of which are not trivial to understand.
The following example shows how to revoke most of an applets restrictions. Any of the permissions can be made more specific, e.g. FilePermission can be given for only selected files, and with read-only access. The javadocs for each Permission class explain in detail what's possible. It is good practice to use the most restricted setting possible. RuntimePermission in particular can be used to create ClassLoaders and SecurityManagers, which can circumvent even more applet restrictions.
Javadocs
JavaDoc:java.awt.AWTPermission
JavaDoc:java.io.FilePermission
JavaDoc:java.lang.RuntimePermission
JavaDoc:java.net.SocketPermission
JavaDoc:java.util.PropertyPermission
Opera 出现问题的原因可能是 Opera 有自己的 java.policy 文件,名为 opera.policy(在 Opera_installation_directory\classes 文件夹下)。 不过,在我的 Opera 安装中,我看不到 Opera 中未授予但默认 java.policy 文件中授予的任何权限。
The reason of having a problem with Opera might be that Opera has its own java.policy file named as opera.policy (under Opera_installation_directory\classes folder). Though, in my Opera installation, I couldn't see any permission that is not granted in Opera but granted in the default java.policy file.