Applet部署在Web頁面中,雖不像圖片可直接「另存為」,但熟練用戶仍可從瀏覽器緩存提取.class文件。通過驗證getDocumentBase()返回的域名,可實現基礎的運行環境綁定保護。
import java.applet.Applet;
import java.net.URL;
public class ProtectedApplet extends Applet {
private static final String ALLOWED_HOST = "www.mydomain.com";
@Override
public void init() {
// 獲取載入Applet的HTML頁面URL
URL docBase = getDocumentBase();
String host = docBase.getHost(); // 僅獲取主機名,不含端口/路徑
// 域名驗證(不區分大小寫)
if (!ALLOWED_HOST.equalsIgnoreCase(host)) {
// 記錄安全日誌
System.err.println("SECURITY ALERT: Unauthorized hosting detected!");
System.err.println("Expected: " + ALLOWED_HOST);
System.err.println("Actual: " + host);
System.err.println("Full URL: " + docBase);
// 拒絕初始化
throw new SecurityException("Applet只能在授權域名運行: " + ALLOWED_HOST);
}
// 正常初始化邏輯
initializeGame();
}
private void initializeGame() {
// 遊戲初始化代碼
}
}
| 方法 | 返回值 | 用途 |
|---|---|---|
getDocumentBase() | URL | 包含Applet的HTML頁面完整URL |
getCodeBase() | URL | Applet.class文件實際下載地址 |
getHost() | String | 僅主機名(如www.example.com) |
getPort() | int | 端口號(-1表示默認端口) |
private static final Set ALLOWED_HOSTS = Set.of(
"www.mydomain.com",
"game.mydomain.com",
"localhost", // 開發環境
"127.0.0.1"
);
// 驗證
if (!ALLOWED_HOSTS.contains(host)) { ... }
private static final String ROOT_DOMAIN = ".mydomain.com";
boolean isAllowed = host.equals("mydomain.com") || host.endsWith(ROOT_DOMAIN);
// 檢查代碼簽名證書
Certificate[] certs = getClass().getProtectionDomain().getCodeSource().getCertificates();
if (certs == null || !verifyCertificate(certs[0])) {
throw new SecurityException("未簽名或簽名無效");
}
hosts將惡意域名解析到授權IP<iframe>或繼承繞過檢查Applet技術已淘汰,現代Web應用保護策略:
Access-Control-Allow-Origin限制調用源域名驗證屬於「誠實用戶」防護,對抗惡意提取需結合代碼簽名、混淆、服務端授權等多層防禦體系。