applet沙箱权限问题
官方解释:
http://download.oracle.com/javase/6/docs/technotes/guides/plugin/developer_guide/security.html
- All unsigned applets are run under the standard applet security model.
- If usePolicy is not defined in the java.policy file, then a signed applet has the AllPermission permission only if Java Plug-in can verify the signers, and the user agrees to granting the AllPermission permission when prompted.
- If usePolicy is defined, then a signed applet has only the permissions defined in java.policy and no prompting occurs.
对于第二点,就是说签了名的一般都是有所有权限的。
但是还需要如下的处理[这个是必要的]
对于签名的applet,
- AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public Object run() throws Exception {
- //you unsafe code
- return null;
- }
- });
我们知道Java applet在浏览器中运行时默认情况下是不能访问本地资源的,比如读写客户端电脑上的文件。这是Java的安全沙箱机制,简单说就是有一组安全检查规 则,要通过检查之后才能访问特定资源。不过在企业应用中这种安全机制有时候并不是十分必要,这里我们就讨论一下在企业应用中突破沙箱检查的方案。
当然,很多朋友会说,这太简单了,只需要改一下java.policy就可以了,授予程序对所有权限就可以了,就像下面这样:
grant {
permission java.security.AllPermission;
};
没错,这样确实可以使客户端applet有权限访问任何资源,但是这个方案有个很实际的问题:java.policy是位于每个客户端电脑的jre 目录下的,如果要修改,那么就需要通知每一个使用该系统的用户,并指导他们做相应操作。这对于搞IT的用户来说是小菜一碟,但对一般业务人员来说却是个额 外的工作,这样的发布方式很难被人认可。
另一个方案——对applet进行签名,用户访问时系统会弹出安全提示框,用户如果信任该程序,点击确认就相当于赋予了这个客户端小程序访问本地资源的权限。这是个很典雅的方案,体现了系统安全和对用户权利的尊重!具体做法大致如下:
1、编写applet,编译并打成jar包
2、对jar包签名
这一步首先要产生证书,利用jdk提供的工具,执行类似下面的命令:
keytool -genkey -keystore d:\mykeys.store -alias test -validity 300
根据系统提示执行完这个命令后会生成一个证书库,上例是:mykeys.store,-validity 300是证书有效期为300天的意思,接下来用这个证书库中的证书给jar包签名,仍然是jdk的工具,命令类似下面:
jarsigner -keystore d:\mykeys.store d:\applet.jar test
3、把applet.jar发布到应用服务器
这个看似完美的方案实际也有一点问题,很多时候我们并不希望把客户端程序都打到一个jar包里,那么多个jar包就需要分别签名,每次修改完客户端程序, 都要重新打包和签名,不然就只有applet能访问本地资源。我们不想这么麻烦,甚至我们有时都不希望对客户端代码打包,这时候签名就不好实现了。那么如 何解决这个问题呢,看下面这招。
既然applet已经被用户授权,那么是否可以在applet里改变安全管理器(SecurityManager)?实验证明是可以的!只需要继承 SecurityManager类,创建自己的安全管理器类,然后覆盖checkPermission方法,允许访问任何资源。在applet的init 方法中调用System.setSecurityManager把安全管理器设置为我们自己的就一切OK了!
至此,我们彻底突破了沙箱检查,而且客户体验很好,完美的方案!
代码很简单,类似于下面这样即可:[这种解决方法我也加了,没有测试是否必须--好像不起作用,没签名的引用包还是报错]
public class MainApplet extends JApplet {
private class DefaultSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm, Object context) {
}
@Override
public void checkPermission(Permission perm) {
}
}
@Override
public void init() {
super.init();
System.setSecurityManager(new DefaultSecurityManager());
}
}
总结:
如果有是默认权限之外的代码:
1:需要签名
2:需要在applet中
- AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public Object run() throws Exception {
- //you unsafe code
- return null;
- }
- });
3:需要用户接受证书
在写skype4java applet时遇到的问题都是关于将包内资源dll加载的问题,winp,skype4java的实现都在applet环境下工作不好,我的解决方法是将其复制到tmp目录下再加载即可。