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号