Apache HttpClient 4.5.x 學習總結十一:HTTP authentication(HTTP認證)
第四章 HTTP認證
HttpClient全面支持HTTP標準認證方案及NTLM、SPNEGO等非標方案。
4.1 用戶憑證
用戶認證需憑證驗證身份,最簡形式是用戶名/密碼對。
UsernamePasswordCredentials類實現包含安全主體和明文密碼的憑證,適用于標準HTTP認證:
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
System.out.println(creds.getUserPrincipal().getName()); // 輸出: user
System.out.println(creds.getPassword()); // 輸出: pwd
NTCredentials是Windows特有憑證,額外包含:
- 工作站名
- 域名
適用于跨域授權的Windows網絡:
NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
System.out.println(creds.getUserPrincipal().getName()); // 輸出: DOMAIN/user
System.out.println(creds.getPassword()); // 輸出: pwd
4.2 認證方案
AuthScheme接口定義認證方案的核心能力:
- 解析服務器的質詢響應
- 提供認證域(realm)等參數
- 生成憑證授權字符串
HttpClient內置方案:
| 方案 | 特點 |
|---|---|
| Basic | 明文傳輸憑證(需配合TLS) |
| Digest | 哈希加密傳輸(比Basic安全) |
| NTLM | Windows專有協議(高安全) |
| SPNEGO | 協商機制(自動選Kerberos/NTLM) |
| Kerberos | 企業級認證(需Active Directory) |
4.3 憑證提供器
CredentialsProvider智能匹配認證作用域:
CredentialsProvider provider = new BasicCredentialsProvider();
// 全局匹配
provider.setCredentials(new AuthScope(null, -1), new UsernamePasswordCredentials("fallback", "pass"));
// 精確匹配
provider.setCredentials(new AuthScope("api.com", 443), new UsernamePasswordCredentials("api", "pass"));
System.out.println(provider.getCredentials(new AuthScope("api.com", 80)));
// 匹配全局憑證 → [principal: fallback]
4.4 認證上下文
通過HttpContext管理認證全周期:
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(provider); // 注入憑證源
context.setAuthCache(authCache); // 注入認證緩存
// 請求后獲取認證狀態
AuthState targetAuth = context.getTargetAuthState();
System.out.println(targetAuth.getAuthScheme()); // 輸出實際使用的認證方案
4.5 認證數據緩存
成功認證后自動緩存憑證(需復用相同上下文)。上下文銷毀時緩存失效。
4.6 預認證
(高風險!慎用)
主動緩存憑證實現免質詢:
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme()); // 預載Basic認證
HttpClientContext context = HttpClientContext.create();
context.setAuthCache(authCache); // 啟用預認證
4.7 NTLM認證
連接復用特性
NTLM認證后連接綁定用戶身份,必須復用相同上下文執行后續請求:
// 首次請求(觸發認證)
httpClient.execute(new HttpGet("/login"), context);
// 復用連接(攜帶身份)
httpClient.execute(new HttpPost("/data"), context);
4.8 SPNEGO/Kerberos認證
工作流程:
- 客戶端請求資源 → 服務器返回
401 Negotiate - 客戶端生成Kerberos票據 → Base64編碼后放入
Authorization頭 - 服務器驗證票據 → 返回
200或繼續協商
配置三要素:
- login.conf - 認證模塊配置
com.sun.security.jgss.initiate { Krb5LoginModule required useTicketCache=true; } - krb5.conf - 域配置
[realms] EXAMPLE.COM = { kdc = kdc.example.com } - Windows注冊表 - 允許票據傳遞
[HKEY_LOCAL_MACHINE\...\Kerberos\Parameters] "allowtgtsessionkey"=dword:00000001
通俗解釋:
場景類比:安全大樓訪問 ??
-
憑證類型
- 基礎憑證 = 門禁卡(卡號+密碼)
- Windows憑證 = 工牌(工號+部門+分機號)
-
認證方案
- Basic = 口頭報卡號(需防竊聽)
- Digest = 動態密碼鎖
- NTLM = 指紋門禁(綁定個人)
- Kerberos = 中央授權系統(需提前領通行證)
-
憑證提供器
graph LR A[訪客] --> B{前臺} B -->|問研發部| C[張三工牌] B -->|問市場部| D[李四工牌] B -->|未指定| E[臨時訪客卡] -
NTLM特性
- 首次進門登記指紋(GET請求觸發認證)
- 后續進出直接通行(復用連接)
- ? 換人必須重新登記(不同身份新建連接)
-
Kerberos配置
login.conf= 聲明使用虹膜識別機krb5.conf= 登記各部門樓層號- 注冊表修改 = 開通虹膜數據同步權限
核心總結:
- 普通場景用Basic+HTTPS
- 內網系統用NTLM(注意連接復用)
- 企業級認證用Kerberos(需域環境)
- 預認證如同提前出示工牌:便捷但有安全風險
浙公網安備 33010602011771號