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,

  1. AccessController.doPrivileged(new PrivilegedExceptionAction() { 
  2.    public Object run() throws Exception { 
  3.    //you unsafe code                                          
  4.        return null; 
  5.    } 
  6. }); 


我们知道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中

  1. AccessController.doPrivileged(new PrivilegedExceptionAction() { 
  2.    public Object run() throws Exception { 
  3.    //you unsafe code                                          
  4.        return null; 
  5.    } 
  6. }); 

3:需要用户接受证书

在写skype4java applet时遇到的问题都是关于将包内资源dll加载的问题,winp,skype4java的实现都在applet环境下工作不好,我的解决方法是将其复制到tmp目录下再加载即可。


Total views.

© 2013 - 2024. All rights reserved.

Powered by Hydejack v6.6.1