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接口定义认证方案的核心能力:

  1. 解析服务器的质询响应
  2. 提供认证域(realm)等参数
  3. 生成凭证授权字符串

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认证

工作流程:

  1. 客户端请求资源 → 服务器返回401 Negotiate
  2. 客户端生成Kerberos票据 → Base64编码后放入Authorization
  3. 服务器验证票据 → 返回200或继续协商

配置三要素:

  1. login.conf - 认证模块配置
    com.sun.security.jgss.initiate {
      Krb5LoginModule required useTicketCache=true;
    }
    
  2. krb5.conf - 域配置
    [realms]
    EXAMPLE.COM = {
      kdc = kdc.example.com
    }
    
  3. Windows注册表 - 允许票据传递
    [HKEY_LOCAL_MACHINE\...\Kerberos\Parameters]
    "allowtgtsessionkey"=dword:00000001
    

通俗解释:

场景类比:安全大楼访问 🏢

  1. 凭证类型

    • 基础凭证 = 门禁卡(卡号+密码)
    • Windows凭证 = 工牌(工号+部门+分机号)
  2. 认证方案

    • Basic = 口头报卡号(需防窃听)
    • Digest = 动态密码锁
    • NTLM = 指纹门禁(绑定个人)
    • Kerberos = 中央授权系统(需提前领通行证)
  3. 凭证提供器

    graph LR A[访客] --> B{前台} B -->|问研发部| C[张三工牌] B -->|问市场部| D[李四工牌] B -->|未指定| E[临时访客卡]
  4. NTLM特性

    • 首次进门登记指纹(GET请求触发认证)
    • 后续进出直接通行(复用连接)
    • ❗ 换人必须重新登记(不同身份新建连接)
  5. Kerberos配置

    • login.conf = 声明使用虹膜识别机
    • krb5.conf = 登记各部门楼层号
    • 注册表修改 = 开通虹膜数据同步权限

核心总结

  • 普通场景用Basic+HTTPS
  • 内网系统用NTLM(注意连接复用)
  • 企业级认证用Kerberos(需域环境)
  • 预认证如同提前出示工牌:便捷但有安全风险
posted @ 2025-07-24 13:32  hqq的进阶日记  阅读(16)  评论(0)    收藏  举报