欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 安全模型,你了解了嗎

 更新時間:2019年06月12日 15:44:31   作者:劉 進  
這篇文章主要介紹了Java 安全模型。Java的安全模型是其多個重要結(jié)構(gòu)特點之一,它使Java成為適用于網(wǎng)絡(luò)環(huán)境的技術(shù)。Java安全模型側(cè)重于保護終端用戶免受從網(wǎng)絡(luò)下載的、來自不可靠來源的、惡意程序(以及善意程序中的bug)的侵犯。,需要的朋友可以參考下

前言

作為一種誕生于互聯(lián)網(wǎng)興起時代的語言,Java 從一開始就帶有安全上的考慮,如何保證通過互聯(lián)網(wǎng)下載到本地的 Java 程序是安全的,如何對 Java 程序訪問本地資源權(quán)限進行有限授權(quán),這些安全角度的考慮一開始就影響到 Java 語言的設(shè)計與實現(xiàn)。可以說 Java 在這些方面的探索與經(jīng)驗,對后來的一些語言與產(chǎn)品都帶來了積極影響。

本篇文章中將介紹 Java 中安全模型,以及如何利用安全訪問控制機制來實現(xiàn)一些特定目的。

Java 中的安全模型

在 Java 中將執(zhí)行程序分成本地和遠程兩種,本地代碼默認視為可信任的,而遠程代碼則被看作是不受信的。對于授信的本地代碼,可以訪問一切本地資源。而對于非授信的遠程代碼在早期的 Java 實現(xiàn)中,安全依賴于沙箱 (Sandbox) 機制。沙箱機制就是將 Java 代碼限定在虛擬機 (JVM) 特定的運行范圍中,并且嚴格限制代碼對本地系統(tǒng)的資源訪問,通過這樣的措施來保證對遠程代碼的有效隔離,防止對本地系統(tǒng)造成破壞。如圖 1 所示,


圖 1.JDK1.0 安全模型

但如此嚴格的安全機制也給程序的功能擴展帶來障礙,比如當用戶希望遠程代碼訪問本地系統(tǒng)的文件時候,就無法實現(xiàn)。因此在后續(xù)的 Java1.1 版本中,針對安全機制做了改進,增加了安全策略,允許用戶指定代碼對本地資源的訪問權(quán)限。如圖 2 所示,

圖 2.JDK1.1 安全模型

在 Java1.2 版本中,再次改進了安全機制,增加了代碼簽名。不論本地代碼或是遠程代碼,都會按照用戶的安全策略設(shè)定,由類加載器加載到虛擬機中權(quán)限不同的運行空間,來實現(xiàn)差異化的代碼執(zhí)行權(quán)限控制。如圖 3 所示,

圖 3.JDK1.2 安全模型

當前最新的安全機制實現(xiàn),則引入了域 (Domain) 的概念。虛擬機會把所有代碼加載到不同的系統(tǒng)域和應(yīng)用域,系統(tǒng)域部分專門負責與關(guān)鍵資源進行交互,而各個應(yīng)用域部分則通過系統(tǒng)域的部分代理來對各種需要的資源進行訪問。虛擬機中不同的受保護域 (Protected Domain),對應(yīng)不一樣的權(quán)限 (Permission)。存在于不同域中的類文件就具有了當前域的全部權(quán)限,如圖 4 所示:


圖 4. 最新安全模型

以上提到的都是基本的 Java 安全模型概念,在應(yīng)用開發(fā)中還有一些關(guān)于安全的復(fù)雜用法,其中最常用到的 API 就是 doPrivileged。doPrivileged 方法能夠使一段受信任代碼獲得更大的權(quán)限,甚至比調(diào)用它的應(yīng)用程序還要多,可做到臨時訪問更多的資源。有時候這是非常必要的,可以應(yīng)付一些特殊的應(yīng)用場景。例如,應(yīng)用程序可能無法直接訪問某些系統(tǒng)資源,但這樣的應(yīng)用程序必須得到這些資源才能夠完成功能。針對這種情況,Java SDK 給域提供了 doPrivileged 方法,讓程序突破當前域權(quán)限限制,臨時擴大訪問權(quán)限。下面內(nèi)容會詳細講解一下安全相關(guān)的方法使用。

Java 安全控制實現(xiàn)

Java SDK 中與安全相關(guān)的類和接口都放在 java.security 包中,其中既包括訪問控制配置及細粒度訪問控制框架的實現(xiàn),還包括簽名和加解密的實現(xiàn)。本文中涉及到的安全訪問控制主要與安全包中訪問控制框架相關(guān),這里面最常用的就是 AccessController 類。通過下圖的描述,您可以了解 ACC(Access Contorller) 機制是如何運作的。

在某一個線程的調(diào)用棧中,當 AccessController 的 checkPermission 方法被最近的調(diào)用程序(例如 A 類中的方法)調(diào)用時,對于程序要求的所有訪問權(quán)限,ACC 決定是否授權(quán)的基本算法如下:

1. 如果調(diào)用鏈中的某個調(diào)用程序沒有所需的權(quán)限,將拋出 AccessControlException;

2. 若是滿足以下情況即被授予權(quán)限:

a. 調(diào)用程序訪問另一個有該權(quán)限域里程序的方法,并且此方法標記為有訪問“特權(quán)”;

b. 調(diào)用程序所調(diào)用(直接或間接)的后續(xù)對象都有上述權(quán)限。

在上面例子的調(diào)用鏈中,假定 E 域和 F 域不具備 X 權(quán)限 (permission),而在 C.class 對應(yīng)的 G 域具有 X 權(quán)限,同時 C 使用 X 權(quán)限的對外接口 Y 方法是通過 doPrivilege 方式實現(xiàn)。那么,B.class A.class 調(diào)用 Y 方法就都具備 X 權(quán)限。如果 Y 方法沒有標注 doPrivilege,那么對 Y 方法的調(diào)用就不具備 X 權(quán)限。

還有一種特殊的情況,就是訪問控制上下文的繼承問題。當一個線程創(chuàng)建另一個新線程時,會同時創(chuàng)建新的堆棧。

如果創(chuàng)建新線程時沒有保留當前的安全上下文,也就是線程相關(guān)的安全信息,則新線程調(diào)用 AccessController.checkPermission 檢驗權(quán)限時,安全訪問控制機制只會根據(jù)新線程的上下文來決定安全性問題,而不會考慮其父線程的相應(yīng)權(quán)限。這個清除堆棧的做法本身并不會給系統(tǒng)帶來安全隱患,但它會使源代碼,尤其是系統(tǒng)代碼的編寫容易出現(xiàn)錯誤。

例如,對安全框架實現(xiàn)不熟悉編程人員可能會很自然地認為,子線程執(zhí)行的信任代碼繼承了父線程執(zhí)行的不可信任代碼的安全限制特性。當從子線程內(nèi)訪問受控制的資源時,如果父線程的安全上下文信息并未保存,就會導(dǎo)致意外的安全漏洞。因為丟失的父線程中安全限制數(shù)據(jù)會使子線程將資源傳遞給一些不可信任的代碼。

因此,在創(chuàng)建新線程時,必須確保利用父線程創(chuàng)建,或利用其他形式創(chuàng)建代碼。總之,要保證讓子線程自動繼承父線程的安全性上下文,這樣子線程中的后續(xù) AccessController.checkPermission 調(diào)用就會考慮所繼承的父線程的安全特性。

需要注意是 AccessController 類的 checkPermission 方法將在當前執(zhí)行線程的上下文,包括繼承的上下文中進行安全檢查。當這種安全檢查只能在不同的上下文中進行時就會出現(xiàn)問題。意即,本應(yīng)在一個線程上下文內(nèi)部進行的安全檢查,有時卻需要在不同上下文中進行。

例如,當一個線程將某個事件傳給另一個線程時,如果所請求的事件服務(wù)要求訪問某種安全受控資源,則為其請求事件服務(wù)的第二個線程將沒有事件產(chǎn)生源線程相應(yīng)的上下文來完成所需的訪問控制決策。為解決這樣的問題,Java 在 AccessController 類中提供了 getContext 方法和 AccessControlContext 對象。通過 getContext 方法可獲取當前調(diào)用上下文的“快照 (snapshot)”,然后將其存放到返回的 AccessControlContext 對象中。調(diào)用的樣例程序如下所示:AccessControlContext acc = AccessController.getContext();

getContext 方法將當前上下文的快照信息捕獲,然后執(zhí)行程序就可以通過檢查前后不同上下文中的信息,即比較快照上下文信息與本上下文信息,然后來做出對受控資源訪問控制的決策。上面問題就可以如下方式來解決,當前一個線程把某個請求事件傳給第二個線程時,同時捕獲其上下文信息并將這些信息提供給后一個線程。

略有不同的是,AccessControlContext 類本身的 checkPermission 方法可根據(jù)它自身攜帶的上下文信息來決定訪問控制,而不是根據(jù)當前正在執(zhí)行的線程上下文。因此必要時,后一個線程可直接通過調(diào)用前一個線程上下文快照本身的權(quán)限檢查方法來執(zhí)行相應(yīng)的安全檢查。

如下,acc.checkPermission(permission),上述方法調(diào)用等同于在前一個線程的上下文中執(zhí)行相同的安全檢查,盡管訪問控制檢查實際上是在后一個線程中完成的。

安全控制使用的代碼實例

上面關(guān)于安全控制使用的描述還是比較晦澀,下面將通過一個代碼示例進行說明。

在 Eclipse 開發(fā)環(huán)境中建立兩個不同工程:projectX 和 projectY。我們會給 projectX 工程中的 bin 目錄賦予寫文件的權(quán)限,換句話說就是允許所有存在于此目錄中的 class 文件可以自由的在 bin 目錄中進行文件寫操作。然后,我們會在 projectY 工程中調(diào)用 projectX 工程中的一個文件操作工具類。這個工具類提供兩種類型接口,一種是特權(quán)訪問方式,另外一種是普通訪問方式。由于在 projectY 工程中的文件是不具備在 projectX 工程中 bin 目錄的任何寫權(quán)限,所以通過三種不同訪問方式的調(diào)用結(jié)果,我們就可以很清楚地了解到 Java 中安全控制該如何使用。

假定 ProjectX 的項目路徑為 D:\workspace\projectX\

package learn.java.security; 
import java.io.File; 
import java.io.IOException; 
import java.security.AccessControlException; 
import java.security.AccessController; 
import java.security.PrivilegedAction; 
public class FileUtil { 
// 工程 A 執(zhí)行文件的路徑 
private final static String FOLDER_PATH = "D:\\workspace\\projectX\\bin"; 
public static void makeFile(String fileName) { 
try { 
// 嘗試在工程 A 執(zhí)行文件的路徑中創(chuàng)建一個新文件
File fs = new File(FOLDER_PATH + "\\" + fileName); 
fs.createNewFile(); 
} catch (AccessControlException e) { 
e.printStackTrace(); 
} catch (IOException e) { 
e.printStackTrace(); 
} 
} 
public static void doPrivilegedAction(final String fileName) { 
// 用特權(quán)訪問方式創(chuàng)建文件
AccessController.doPrivileged(new PrivilegedAction<String>() { 
@Override 
public String run() { 
makeFile(fileName); 
return null; 
} 
}); 
} 
}

假定 ProjectY 的項目路徑為 D:\workspace\projectY\

package demo.security; 
import java.io.File; 
import java.io.IOException; 
import java.security.AccessControlException; 
import learn.java.security.FileUtil; 
public class DemoDoPrivilege { 
public static void main(String[] args) { 
System.out.println("***************************************"); 
System.out.println("I will show AccessControl functionality..."); 
System.out.println("Preparation step : turn on system permission check..."); 
// 打開系統(tǒng)安全權(quán)限檢查開關(guān)
System.setSecurityManager(new SecurityManager()); 
System.out.println(); 
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 
System.out.println("
Create a new file named temp1.txt via privileged action ..."); 
// 用特權(quán)訪問方式在工程 A 執(zhí)行文件路徑中創(chuàng)建 temp1.txt 文件
FileUtil.doPrivilegedAction("temp1.txt"); 
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 
System.out.println(); 
System.out.println("http://///////////////////////////////////////"); 
System.out.println("Create a new file named temp2.txt via File ..."); 
try { 
// 用普通文件操作方式在工程 A 執(zhí)行文件路徑中創(chuàng)建 temp2.txt 文件
File fs = new File( 
"D:\\workspace\\projectX\\bin\\temp2.txt"); 
fs.createNewFile(); 
} catch (IOException e) { 
e.printStackTrace(); 
} catch (AccessControlException e1) { 
e1.printStackTrace(); 
} 
System.out.println("http://///////////////////////////////////////"); 
System.out.println(); 
System.out.println("-----------------------------------------"); 
System.out.println("create a new file named temp3.txt via FileUtil ..."); 
// 直接調(diào)用普通接口方式在工程 A 執(zhí)行文件路徑中創(chuàng)建 temp3.txt 文件
FileUtil.makeFile("temp3.txt"); 
System.out.println("-----------------------------------------"); 
System.out.println(); 
System.out.println("***************************************"); 
} 
}

應(yīng)用的安全訪問控制策略文件 (MyPolicy.txt) 如下 , 假定安全策略文件放于 projectY 工程的根目錄下:

// 授權(quán)工程 A 執(zhí)行文件路徑中文件在本目錄中的寫文件權(quán)限
grant codebase "file:/D:/workspace/projectX/bin"
{ 
permission java.io.FilePermission 
"D:\\workspace\\projectX\\bin\\*", "write"; 
};

下面就可以運行程序了,您可以選擇在 Eclipse 開發(fā)環(huán)境中直接運行,也可以通過命令行來執(zhí)行。命令行執(zhí)行如下所示,假定當前執(zhí)行目錄就是 projectY 的根目錄。

java -Djava.security.policy=.\\MyPolicy.txt -classpath 
D:\workspace\projectY\bin;D:\workspace\projectX\bin demo.security.DemoDoPrivilege

執(zhí)行結(jié)果如下:

*************************************** 
I will show AccessControl functionality... 
Preparation step : turn on system permission check... 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
Create a new file named temp1.txt via privileged action ... 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//////////////////////////////////////// 
Create a new file named temp2.txt via File ... 
java.security.AccessControlException: Access denied (java.io.FilePermission 
D:\workspace\projectX\bin\temp2.txt write) 
at java.security.AccessController.checkPermission(AccessController.java:108) 
at java.lang.SecurityManager.checkPermission(SecurityManager.java:533) 
at java.lang.SecurityManager.checkWrite(SecurityManager.java:963) 
at java.io.File.createNewFile(File.java:882) 
at demo.security.DemoDoPrivilege.main(DemoDoPrivilege.java:32) 
//////////////////////////////////////// 
---------------------------------------- 
create a new file named temp3.txt via FileUtil ... 
java.security.AccessControlException: Access denied (java.io.FilePermission 
D:\workspace\projectX\bin\temp3.txt write) 
at java.security.AccessController.checkPermission(AccessController.java:108) 
at java.lang.SecurityManager.checkPermission(SecurityManager.java:533) 
at java.lang.SecurityManager.checkWrite(SecurityManager.java:963) 
at java.io.File.createNewFile(File.java:882) 
at learn.java.security.FileUtil.makeFile(FileUtil.java:16) 
at demo.security.DemoDoPrivilege.main(DemoDoPrivilege.java:43) 
---------------------------------------- 
***************************************

通過程序打印結(jié)果來看,當往 projectX 工程中 bin 目錄創(chuàng)建 temp1.txt,temp2.txt,temp3.txt 文件時候,除了通過特權(quán)訪問方式可以創(chuàng)建成功外,通過普通接口訪問或者直接文件操作方式都會失敗,失敗的原因都是沒有通過權(quán)限檢查。對照前文所描述的權(quán)限檢查規(guī)則,用一句話總結(jié)就是想訪問安全資源,要么調(diào)用鏈上權(quán)限齊全,要么就要用特權(quán)。

特權(quán)訪問機制實際上就是給應(yīng)用開后門的使用上需要小心,所以這也給代碼實現(xiàn)帶來新的考慮,開放范圍一定要限定好,否則可能留下安全隱患。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java常見內(nèi)存溢出異常分析與解決

    Java常見內(nèi)存溢出異常分析與解決

    本篇文章主要分析了JAVA程序內(nèi)存溢出問題原因,較為詳細的說明了java導(dǎo)致程序內(nèi)存溢出的原因與解決方法,感興趣的小伙伴們可以參考一下。
    2016-10-10
  • @RequestParam注解加與不加有什么區(qū)別

    @RequestParam注解加與不加有什么區(qū)別

    這篇文章主要介紹了@RequestParam注解加與不加有什么區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • JVM入門之內(nèi)存結(jié)構(gòu)(堆、方法區(qū))

    JVM入門之內(nèi)存結(jié)構(gòu)(堆、方法區(qū))

    JVM 基本上是每家招聘公司都會問到的問題,它們會這么無聊問這些不切實際的問題嗎?很顯然不是。由 JVM 引發(fā)的故障問題,無論在我們開發(fā)過程中還是生產(chǎn)環(huán)境下都是非常常見的
    2021-06-06
  • java中charAt()方法的使用及說明

    java中charAt()方法的使用及說明

    這篇文章主要介紹了java中charAt()方法的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring-Security對HTTP相應(yīng)頭的安全支持方式

    Spring-Security對HTTP相應(yīng)頭的安全支持方式

    這篇文章主要介紹了Spring-Security對HTTP相應(yīng)頭的安全支持方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • java實現(xiàn)客戶管理系統(tǒng)

    java實現(xiàn)客戶管理系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)客戶管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • java實現(xiàn)文件變化監(jiān)控的方法(推薦)

    java實現(xiàn)文件變化監(jiān)控的方法(推薦)

    下面小編就為大家?guī)硪黄猨ava實現(xiàn)文件變化監(jiān)控的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 使用SpringMVC的@Validated注解驗證的實現(xiàn)

    使用SpringMVC的@Validated注解驗證的實現(xiàn)

    這篇文章主要介紹了使用SpringMVC的@Validated注解驗證的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Spring自動裝配@Autowired教程

    Spring自動裝配@Autowired教程

    @Autowired注解是Spring中非常重要且常見的,接下來就簡要的介紹一下它的用法。@Autowired默認是通過set方法,按照類型自動裝配JavaBean,set方法可省略不寫,它主要是修飾在成員變量上
    2023-01-01
  • 淺談Java中復(fù)制數(shù)組的方式

    淺談Java中復(fù)制數(shù)組的方式

    這篇文章主要介紹了Java中復(fù)制數(shù)組的幾種方法,需要的朋友可以參考下。
    2017-08-08

最新評論