使用 SecurityManager 和 Policy File 管理 Java 程序的權限


參考資料##

該文中的內容來源於 Oracle 的官方文檔。Oracle 在 Java 方面的文檔是非常完善的。對 Java 8 感興趣的朋友,可以從這個總入口 Java SE 8 Documentation 開始尋找感興趣的內容。本博客不定期從 Oracle 官網搬磚。

前言##

Java 在 Security 方面的特性,總是被很多人當做宣傳的重點,但是對我而言,這基本上是八百年都用不到一次的特性。可是沒辦法,為了知識體系的完整性,我也不得不硬着頭皮學習這些八竿子都打不着的內容。

很多 Java 程序默認在一個安全的環境中運行,比如 Applet程序。當這些在安全環境中運行的程序需要訪問我們系統中的資源時,就會受到限制。換句話說,就是當 Applet 之類的程序運行時,默認就會啟動一個 SecurityManager,SecurityManager 負責檢查該程序是否具有相應的權限。但是很多 Java 程序不會默認啟動 SecurityManager,比如大部分在我們系統中直接運行的 Java 程序。沒有啟用 SecurityManager 的程序的權限不會受到限制,如果存在惡意代碼的話,就會產生安全問題。如果我們非要放寬對它們的限制的話,就需要對相應的 Java 程序進行授權,授權需要用到 Policy File。

沒有啟用 SecurityManager 的程序可以訪問系統中的任意資源##

廢話少說,直接開始實戰。先看兩個示例程序,GetProps.javaCount.java,它們一個需要訪問 Java 運行環境中的 Properties,一個需要讀取磁盤上的文件。代碼如下圖:

編譯、打包、運行,這兩個程序的運行結果非常符合預期,如下圖:

從上圖中可以看出,我在打包的時候沒有使用 jar-e 選項指定程序的入口點,只是簡單的把所有的 .class 打成一個 jar 包而已。運行的時候使用 java -cp HelloWorld.jar 將該 jar 包指定為 CLASSPATH 並直接運行其中的類。其實這里的程序不打包也可以運行,但是要對程序進行簽名,就必須得打包了。

啟用了 SecurityManager 的程序權限會被限制##

如果啟用 SecurityManager,則程序的權限會受到限制。怎么啟用 SecurityManager 呢?有兩個辦法,一個辦法是在啟動程序的使用使用 java -Djava.security.manager 選項,另一個辦法是在代碼中使用 System.setSecurityManager(new SecurityManager());。先看下圖,使用第一種辦法開啟 SecurityManager:

可以看到,一旦使用 java -Djava.security.manager 選項啟動,程序 GetPropsCount 都產生了異常。我們也可以在代碼中啟用 SecurityManager,也可以手動調用 SecurityManager 的方法來驗證運行的程序是否具有相應的權限。請看下圖示例程序 SecurityOnByCode.java

編譯、打包、運行,果然產生了異常,如下圖:

使用 Policy File 為程序授權##

如果要讓啟用了 SecurityManager 的程序正常運行,就必須對它們進行相應的授權。在本例中,需要對 GetPropsSecurityOnByCode 示例程序授予它訪問 System Properties 的權限,為 Count 示例程序授予訪問目錄 src/com/xkland/sample 中文件的權限。授權是使用 Policy File 來控制的。系統中有一個全局的 Policy File,它的路徑是 ${java.home}/lib/security/java.policy,另外還可以為當前用戶定義一個用戶級別的 Policy File,只要這個文件的路徑是 ${user.home}/.java.policy 就行。也可以編寫其它的任意的 Policy File,只需要在啟動程序的時候用 java -Djava.security.policy= 選項指定 Policy File 的路徑即可。

在 JDK 提供的工具中,有一個 policytool,這是一個 GUI 程序,它可以極大地簡化我們編寫 Policy File 的過程,后面的實戰中會用到它。首先,先來為需要訪問 System Properties 的程序授權,我制定一個這樣的策略:位於 ${user.home}/HelloJavaWorld 目錄下的程序可以訪問 System Properties,這就需要用到基於 CodeBase 的授權。在本例中,我使用 policytool 創建一個 youxia.policy 文件,並基於 CodeBase 授予相應的訪問 System Properties 的 java.util.PropertyPermission,如下圖:

可以使用 cat youxia.policy 命令查看生成的 Policy File 的內容。授權之后再運行 GetProps 程序和 SecurityOnByCode 程序,發現它們都能順利運行,沒有產生任何異常,如下圖:

但是另外一個程序 Count 仍然受限的,因為我們沒有給它授予訪問文件的權限。下面來解決這個問題,我設計的策略是如果該程序是被 youxia 的證書簽名的,則授予它訪問 src/com/xkland/sample 目錄下所有文件的權利。這就需要用到基於 SignedBy 的授權。使用該類型的授權必須先指定密鑰庫(keystore),而密鑰庫的類型、供應方和口令是可以留空的,如下圖:

然后再添加相應的授權,如下圖:

最后來看運行效果。先常規使用 cat youxia.policy 看看,發現 Policy File 中多了一個 Grant SignedBy "youxia" 的條目,然后對 HelloWorld.jar 使用 youxia 的證書進行簽名,最后運行程序,結果一切正常。如下圖:

總結##

Java 領域中一些關於安全的特性往往是商家宣傳的重點,但是對於我們普通開發者而言,用到這些特性的機會很少,因此往往會比較陌生。關於證書和密鑰庫的內容,請看這里 JDK中的證書生成和管理工具keytool, 關於 jar 文件簽名和驗證的內容,請看這里 Java程序的打包、簽名和驗證。這一篇中涉及到的 SecurityManager 和 Policy File 本身並不難,按我這個實戰的流程走一遍即可了然於胸。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM