注意:本文出自 “阿飛”的部落格 ,如果要轉載本文章,請與作者聯絡!並註明來源: http://blog.csdn.net/faye0412/article/details/7037078
這兩天忽然收到cs部門的反饋說一個項目出問題了,一看,噢噢噢,原來是幾年前做的一個Applet的項目,在用戶端無論使用什麼瀏覽器都無法正常運行,我檢查了一下,異常資訊如下:
java.security.AccessControlException: access denied (java.io.FilePermission "<<ALL FILES>>", "execute")...
.....<其他資訊省略>
這個問題在開發的時候也曾經遇到過,後來簽名後解決了,但是最近為啥又冒出來了呢?奇怪....
我又找了N台機器,不同版本的瀏覽器(ie7,8,9...Cheome, Firefox....)都測了一遍發現一個問題:
1. 與瀏覽器無關,而是與jre的版本有關;
2. jre版本高於1.6.0_20的都不能正常運行,低於該版本的都可以正常運行(我的是JRE 版本 1.6.0_29-b11,不能運行);
如何解決呢?於是我找了Oracle裡N多相關的文檔,比如:
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html(簽名Applet)
http://docs.oracle.com/javase/1.4.2/docs/guide/security/permissions.html(Permissions in the JavaTM 2 SDK)
等等,都沒啥進展。我嘗試了如下方法:
1. 定義私人policy檔案的方法;
2. 修改Java預設安全性原則檔案(不太安全), ${java.home}/lib/security/java.security檔案,增加授權方式;
都沒起作用(可能是我沒弄對?),但是我們不能讓每一個客戶都去修改他們自己的安全性原則檔案,畢竟不是每一個人都那麼專業,客戶也不會願意接受這種方式的。
問題解決:
後來在翻閱文檔後發現了一個重要的方法,可以很快速的解決我的問題,那就是:使用AccessController.doPrivileged提升代碼許可權!如果不期望用戶端修改JRE中的安全配置,可以選擇在代碼中提升,而這個就是我所期待的!
在用戶端彈出的jdk的對話方塊中只要使用者點擊信任,運行按鈕,也就是說如果信任此簽名,將可以執行此代碼:AccessController.doPrivileged(...),Applet許可權也將得到提升。
具體範例程式碼如下:
private String runCmd(){String result = AccessController.doPrivileged(new PrivilegedAction<String>() { @Override public String run() { String res = null;//TODO like 'Runtime.getRuntime().exec(cmd)' etc..... return res; } });return result;}
就這樣,簡單的幾句話就搞定了。。。。
別忘了,最後需要做的是重新打jar包,簽名,然後將認證和keystore檔案,jar檔案重新發布到伺服器測試:)
補充:
之前也曾寫過一篇文章《關於JS調用Applet的執行許可權的問題》(http://blog.csdn.net/faye0412/article/details/4566400),裡面提到了使用SwingUtilities.invokeLater(new Runnable()...的方式,但是這種方法只能解決之前的簽名和Applet假死的情況,不能解決現在遇到的這種情況,所以,最好的方式是結合這兩種方法使用。問題完美解決!!