多套 B/S 系統需頻繁輸入用戶名密碼,單點登錄 (SSO) 改造成本高。尋找輕量級「自動填表登錄」方案:客戶端程序 (C/S) 一鍵打開瀏覽器並自動登入目標系統。
URL url = new URL(loginUrl);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
try (OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream())) {
out.write("username=admin&password=123456");
out.flush();
}
// 讀取響應...
String content = readResponse(conn.getInputStream());
System.out.println(content); // 控制台顯示「登錄成功」
問題:僅在**服務端建立 Session**,返回的 Set-Cookie (JSESSIONID) 在**客戶端程序內存中**,無法共享給**瀏覽器進程**。瀏覽器打開系統頁面仍需手動登錄。
在 C/S 程序內嵌 JEditorPane / JavaFX WebView / JxBrowser / CEF,共享 CookieManager。可行但**體積大、維護難、渲染兼容性差**,非輕量級方案。
核心思想:利用 JSP 作為「登錄頁面鏡像」,服務端輸出包含**目標登錄表單 HTML + 自動填充腳本 + 自動提交**的完整頁面,瀏覽器直接訪問此 JSP 即可完成登錄並跳轉至目標系統主頁。
login_template.html)。autoLogin.jsp:
<%@ page import="java.io.*,java.net.*,java.util.*" contentType="text/html;charset=UTF-8" %>
<%
// 1. 獲取加密參數 (用戶名、密碼、有效期、簽名)
String encParam = request.getParameter("token");
// 2. 解密驗證 (略)
String username = decrypt(encParam, "username");
String password = decrypt(encParam, "password");
// 3. 代理請求目標登錄頁 (可選:獲取動態 CSRF Token、驗證碼)
// URLConnection conn = ... POST 登錄 ...
// String sessionId = extractSessionId(conn); // 若需後續操作
%>
Auto Login
// 生成帶簽名、有效期的 Token
String token = encryptAndSign("username=admin&password=123456&expire=300");
// 唚起瀏覽器
Process.Start("https://my-proxy.com/autoLogin.jsp?token=" + URLEncoder.encode(token, "UTF-8"));
| 環節 | 方案 | 注意事項 |
|---|---|---|
| 憑證傳遞 | URL 參數加密 (AES-GCM) + 簽名 (HMAC) + 短效期 (如 5 分鐘) | 防止 Token 洩露被重放攻擊,**嚴禁明文傳輸密碼** |
| 動態 Token | JSP 中先用 HttpClient 訪問登錄頁獲取 CSRF Token / 驗證碼,再構造表單 | 目標站若有反爬蟲/動態表單,此步必須 |
| Session 共享 | JSP 代理登錄後,瀏覽器直接獲得目標站 Cookie,後續訪問無感知 | 核心優勢:真正實現「一鍵免登」 |
| HTTPS | 全鏈路強制 HTTPS | 保護傳輸中憑證 |