| 版本 | 權限模型 | 特點 |
| JDK 1.0 | 二元模型 | 完全信任 / 沙箱權限,無中間狀態 |
| JDK 1.1+ | 細粒度權限 | Permission 集合組合,支持文件/網絡/屬性等精確控制 |
| JDK 1.2+ | 基於域的保護域 | CodeSource (位置+簽名者) → ProtectionDomain → Permission 集合 |
實戰案例:可讀寫本地文件的 Applet
1. Applet 核心代碼
package jcomponent;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class FileReaderApplet extends Applet {
TextField fileNameField;
TextArea fileArea;
public void init() {
setLayout(new BorderLayout());
Panel top = new Panel();
top.add(new Label("File Name"));
fileNameField = new TextField(25);
top.add(fileNameField);
Button openBtn = new Button("Open File");
openBtn.addActionListener(e -> loadFile(fileNameField.getText()));
top.add(openBtn);
add(top, BorderLayout.NORTH);
fileArea = new TextArea();
add(fileArea, BorderLayout.CENTER);
}
void loadFile(String fileName) {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) {
fileArea.append(line + "\n");
}
} catch (IOException ex) {
fileArea.append("IO Error: " + ex.getMessage());
} catch (SecurityException ex) {
fileArea.append("Security Error: " + ex.getMessage());
}
}
}
2. 打包 JAR 文件
# 編譯
javac jcomponent/FileReaderApplet.java
# 打包
jar -cvf MyApplet.jar jcomponent/*.class
3. 生成密鑰庫與自簽名證書
# 生成密鑰對 (別名: pepper, 密鑰庫: pepper.store)
keytool -genkey -keystore pepper.store -alias pepper
# 輸入密鑰庫密碼、密鑰密碼、證書信息 (CN=YourName, OU=Dev, O=Company, L=City, ST=State, C=CN)
# 導出證書文件 (供客戶端導入信任)
keytool -export -keystore pepper.store -alias pepper -file pepper.cert
4. 簽名 JAR 文件
jarsigner -keystore pepper.store MyApplet.jar pepper
# 輸入密鑰庫密碼、密鑰密碼
# 驗證簽名
jarsigner -verify -verbose MyApplet.jar
5. 編寫安全策略文件 (applet.policy)
keystore "file:c:/admin/pepper.store", "JKS";
grant signedBy "pepper" {
permission java.io.FilePermission "<>", "read,write,delete";
// 可根據需要添加其他權限
// permission java.net.SocketPermission "*", "connect,resolve";
// permission java.util.PropertyPermission "*", "read,write";
};
關鍵語法:
keystore 指定信任的密鑰庫位置
signedBy "pepper" 匹配簽名者別名
FilePermission 目標模式:file、dir/、dir/*、dir/-、<>
- 動作:
read、write、delete、execute
6. 註冊策略文件到 Java 安全配置
編輯 ${java.home}/jre/lib/security/java.security:
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
policy.url.3=file:c:/admin/applet.policy # 新增行
7. HTML 部署與瀏覽器適配
<APPLET
CODEBASE="."
CODE="jcomponent.FileReaderApplet.class"
ARCHIVE="MyApplet.jar"
WIDTH=400 HEIGHT=300
NAME="TestApplet">
</APPLET>
為支持舊版瀏覽器/插件,運行 HTMLConvert 工具轉換為 <OBJECT>/<EMBED> 標籤,指定 codebase 指向 JRE 插件下載地址。
生產環境部署架構
服務端目錄結構 (映射為 https://www.example.com/admin/):
├── MyApplet.jar # 簽名後的 JAR
├── pepper.cert # 公鑰證書 (供用戶導入)
├── pepper.store # 密鑰庫 (策略文件引用)
├── applet.policy # 策略文件 (keystore 用 HTTP URL)
└── FileReaderApplet.html # 網頁頁面
客戶端僅需修改 java.security:
policy.url.3=https://www.example.com/admin/applet.policy
關鍵安全最佳實踐
- 最小權限原則:策略文件僅授予必要權限(如僅讀特定目錄),避免
<>
- 證書管理:生產環境應購買受信 CA 簽發的代碼簽名證書,而非自簽名
- 時間戳服務:簽名時添加
-tsa https://timestamp.digicert.com,證書過期後簽名仍有效
- 混合代碼防護:JAR 清單添加
Trusted-Library: true、Permissions: sandbox 屬性防止混合簽名攻擊
- 部署規範:使用 JNLP/Web Start 替代 Applet 标签(Java 9+ 已移除 Applet API)
現代替代方案(Applet 已淘汰)
注意:Java 9 標記棄用,Java 11 移除 Applet API,瀏覽器已停止支持 NPAPI 插件。
| 場景 | 現代替代技術 |
| 本地文件訪問 | Java Web Start (JNLP) / JavaFX 獨立應用 / Electron + Node.js |
| 瀏覽器內運行 | WebAssembly (Rust/Go/C++) / PWA + File System Access API |
| 企業內部分發 | MSI/EXE 安裝包 / Docker 容器 / 應用商店分發 |
總結
本文完整演示了「代碼簽名 + 安全策略」賦予 Applet 受信權限的經典流程。雖然 Applet 技術已退出歷史舞台,但其核心安全模型——CodeSource → ProtectionDomain → Permission → AccessController.checkPermission——仍是 Java 安全架構的基石,廣泛應用於 Java EE 容器安全、插件系統權限隔離、移動端應用沙箱等現代場景。理解這套機制對於 Java 高級開發、安全審計、架構設計具有持久價值。
- 上一篇文章: Java 用戶界面本地化(i18n)完整實戰指南:ResourceBundle 與 Locale 實踐
- 下一篇文章: 深度解析 EJB 2.0 消息驅動 Bean (MDB):異步消息處理核心組件
Copyright ©
程式碼之家 All Rights Reserved