原文链接 译者:edenpan
4 HTTP 验证
httpClient 对根据HTTP 标准规则制定的权限验证方案,以及很多不标准但广泛使用的验证方案,比如:NTML和SPNEGO提供完全的支持。
4.1 用户凭证
任何一个用户验证程序需要一系列的凭证信息用来确认用户身份。最简单的用户凭证就是用户名/密码。UsernamePasswordCredentials 代表由明文形式的安全主体和密码组成的一组凭证。这个实现足够作为标准的根据HTTP标准规范定义的安全验证规则。
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());
stdout>
user
pwd
NTCredentials是微软Windows特有的一个认证方式,包括对用户名/密码添加另外的Windows的属性,比如用户域的名称。在一个Microsoft Windows network中一个相同的用户可以属于多个域并且有不同的凭证。
NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());
stdout>
DOMAIN/user
pwd
4.2 认证方案
AuthScheme 接口代表一个抽象的挑战-响应(challenge-response)认证方案。一个认证方案希望支持以下功能:
- 解析和响应目标服务器发送的挑战,回应对受保护资源的请求。
- 提供被处理的挑战的属性:认证方案类型以及参数,比如这个方案可以适用的领域(如果可行)。
- 对指定的证书和http请求生成认证字符串用来回应实际的认证挑战。
请注意认证方案也许是有状态的,涉及一系列challenge-response 的交换。
HttpClient 附带几个AuthScheme实现:
- 基础(Basic):RFC2617中定义的基础认证方案。这个认证方案是不安全的因为凭证是用明文传送。尽管如此如果和TSL/SSL加密结合使用 这个认证方案是完全足够的。
- 摘要(Digest):RFC2617中定义的摘要认证方案。摘要认证方案明显的比基础方案更加安全,并且对于不想使用TLS/SSL加密的应用是一个很好的选择。
NTLM:NTLM是一个有Microsoft开发并且针对Windows平台进行了优化的专有验证方案。它被认为比摘要方案要更加安全。
SPNEGO:SPNEGO(简单受保护的GSSAPI协商机制)是一个GSSAPI的“伪机制”被用于协商许多可能的真实机制。它最明显的用途是在Microsoft’s HTTP Negotiate 的认证扩展中。这个协商子机制包含了NTLM以及被Active Directory支持的Kerberos。目前HttpClient只支持Kerberos 子机制。
Kerberos:Kerberos认证方案的实现。
4.3 凭证提供者
凭证提供者旨在维护一系列的用户凭证以及可以在特定的认证范围内产生用户凭证。
认证范围由主机名,端口号,域名和认证方案名组成。当在凭证提供者注册凭证时,可以使用通配符(任意的主机名,端口,域与方案)而不仅仅是一个具体的值。凭证提供者被希望可以在没有找到完全符合的情况下可以在特定的范围内查到最相近的值。
HttpClient 可以和任何实际实现了CredentialsProvider接口的凭据提供者合作。默认的CredentialsProvider接口实现为:BasicCredentialsProvider:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("somehost", AuthScope.ANY_PORT),
new UsernamePasswordCredentials("u1", "p1"));
credsProvider.setCredentials(
new AuthScope("somehost", AuthScope.ANY_PORT),
new UsernamePasswordCredentials("u1", "p1"));
credsProvider.setCredentials(new AuthScope("somehost", 8080), new UsernamePasswordCredentials("u2", "p2"));
credsProvider.setCredentials(
new AuthScope("otherhost", 8080, AuthScope.ANY_REALM, "ntlm"),
new UsernamePasswordCredentials("u3", "p3"));
System.out.println(credsProvider.getCredentials(new AuthScope("somehost", 80, "realm", "basic")));
System.out.println(credsProvider.getCredentials(new AuthScope("somehost", 8080, "realm", "basic")));
System.out.println(credsProvider.getCredentials(new AuthScope("otherhost", 8080, "realm", "basic")));
System.out.println(credsProvider.getCredentials(new AuthScope("otherhost", 8080, null, "ntlm")));
stdout>
[principal: u1]
[principal: u2]
null
[principal: u3]
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/114100.html