《HttpClient官方文档》HTTP验证4.4-4.7

4.4 HTTP验证和执行上下文

HttpClient依赖于AuthState类来追踪验证进程的状态的详细信息。HttpClient在执行HTTP请求执行时,创建AuthState的两个实例:一个对目标主机认证,另外一个用于代理认证。一旦目标主机或者代理要求用户验证,对应的AuthState实例将会在验证过程中被AuthScope,AuthScheme和Crednetials填充。这个AuthState可以被检查用于找出哪种类型要求验证,是否对应的AuthScheme被找到,以及凭证提供者可以找到在给定的验证范围内找到用户凭证。

在HTTP请求过程中HttpClient添加了以下的验证关系对象到执行上下文中:

  • Lookup 实例代表实际的验证方案注册。这个属性值在本地上下文中优先与默认值被设置。
  • CredentialsProvider实例代表实际的凭证提供者。这个属性值本地上下文中优先与默认值被设置。
  • AuthState实例代表实际的目标验证状态。这个属性值本地上下文中优先与默认值被设置。
  • AuthState实例代表实际的代理验证状态。这个属性值本地上下文中优先与默认值被设置。
  • AuthCache实例代表实际的验证数据缓存。这个属性值本地上下文中优先与默认值被设置。

这个本地的HttpContext对象可以在请求执行之前定制HTTP验证上下文或者在请求被执行后检查它的状态:

CloseableHttpClient httpclient = <...>
CredentialsProvider credsProvider = <...>
Lookup<AuthSchemeProvider> authRegistry = <...>
AuthCache authCache = <...>
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthSchemeRegistry(authRegistry);
context.setAuthCache(authCache);
HttpGet httpget = new HttpGet("http://somehost/");
CloseableHttpResponse response1 = httpclient.execute(httpget, context);
<...>
AuthState proxyAuthState = context.getProxyAuthState();
System.out.println("Proxy auth state: " + proxyAuthState.getState());
System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
AuthState targetAuthState = context.getTargetAuthState();
System.out.println("Target auth state: " + targetAuthState.getState());
System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
System.out.println("Target auth credentials: " + targetAuthState.getCredentials());

4.5 验证数据缓存

从4.1版本开始HttpClient自动缓存验证成功的主机的信息。请注意为了使缓存的验证数据从一个请求传播到另外一个请求上,必须使用相同的上下文来执行相关的逻辑请求。如果执行上下文超出了范围,验证数据将会很快丢失。

4.6 抢占式验证

HttpClient 不支持抢占试验证因为如果错误使用抢占式验证会导致明显的安全问题,比如明文发送用户凭证到第三方没有验证的组织。除此之外用户被期望在他们自己的应用环境中自己来评估抢占式验证的潜在好处和安全风险。
尽管如此可以通过配置HttpClient预填充验证数据到缓冲中来实现抢占式验证。
CloseableHttpClient httpclient = <…>

HttpHost targetHost = new HttpHost("localhost", 80, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
        new AuthScope(targetHost.getHostName(), targetHost.getPort()),
        new UsernamePasswordCredentials("username", "password"));

// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);

// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpGet httpget = new HttpGet("/");
for (int i = 0; i < 3; i++) {
    CloseableHttpResponse response = httpclient.execute(
            targetHost, httpget, context);
    try {
        HttpEntity entity = response.getEntity();
    } finally {
        response.close();
    }
}

4.7 NTLM验证

自从4.1HttpClient版本对NTLMv1, NTLMv2, and NTLM2会话验证提供完全的支持。外部的NTML引擎比如由Samba项目开发的JCIFS库作为其Windows互操作性程序套件的一部分仍然可以被使用。

4.7.1 NTLM连接持久化

NTLM验证方案比标准的Basic和Digest方案要明显消耗更多的计算性能。这也许是微软选择使NTLM验证方案状态话的主要原因。只要验证成功了,这个用户的标志会和它整个连接的寿命相关。NTLM有状态的特性使连接持久化更加复杂,一个明显的原因:连接持久化的NTLM不能被不同的用户标识进行重用。无论如何在同一个会话中逻辑相关的请求使用相同的执行上下文来保证它们意识到当前用户的身份。否则HttpClient将会针对每一个NTLM保护请求的每一个Http请求创建一个新的HTTP连接。对于状态话的HTTP请求的详细讨论请参考这个页面
由于NTLM是状态话的,它一般推荐使用相对便宜的方式来触发NTLM验证,比如GET或者HEAD,以及复用相同的连接来执行更加昂贵的操作,特别是包含了请求实体的比如POST或者PUT。

CloseableHttpClient httpclient = <...>
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
        new NTCredentials("user", "pwd", "myworkstation", "microsoft.com"));

HttpHost target = new HttpHost("www.microsoft.com", 80, "http");

// Make sure the same context is used to execute logically related requests
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);

// Execute a cheap method first. This will trigger NTLM authentication
HttpGet httpget = new HttpGet("/ntlm-protected/info");
CloseableHttpResponse response1 = httpclient.execute(target, httpget, context);
try {
    HttpEntity entity1 = response1.getEntity();
} finally {
    response1.close();
}

// Execute an expensive method next reusing the same context (and connection)
HttpPost httppost = new HttpPost("/ntlm-protected/form");
httppost.setEntity(new StringEntity("lots and lots of data"));
CloseableHttpResponse response2 = httpclient.execute(target, httppost, context);
try {
    HttpEntity entity2 = response2.getEntity();
} finally {
    response2.close();
}

转载自 并发编程网 - ifeve.com

时间: 2024-10-04 19:29:39

《HttpClient官方文档》HTTP验证4.4-4.7的相关文章

《HttpClient官方文档》4.8 SPNEGO/Kerberos验证

SPNEGO(简单并且受保护的GSSAPI协商机制)被设计为当两端都不知道他人可以提供,或使用什么时所提供的验证服务.它可以包装其他的机制,但是目前HttpClient4.2是按照Kerbros单独设计的. 4.8.1SPNEGO在HttpClient中的支持 SPNEGO验证方案被Sun Java 1.5以上版本兼容.1.6以上的Java版本被强烈推荐,因为它已经完全支持了SPNEGO验证. Sun JRE 提供了相关支持类来处理几乎所有的Kerb er和SPNEGO的令牌.这意味着很多步骤是

《HttpClient官方文档》4.1-4.3 HTTP验证

4 HTTP 验证 httpClient 对根据HTTP 标准规则制定的权限验证方案,以及很多不标准但广泛使用的验证方案,比如:NTML和SPNEGO提供完全的支持. 4.1 用户凭证 任何一个用户验证程序需要一系列的凭证信息用来确认用户身份.最简单的用户凭证就是用户名/密码.UsernamePasswordCredentials 代表由明文形式的安全主体和密码组成的一组凭证.这个实现足够作为标准的根据HTTP标准规范定义的安全验证规则. UsernamePasswordCredentials

《HttpClient官方文档》2.7 连接套接字工厂

2.7. Socket连接工厂 HTTP连接在内部使用java.net.Socket类的对象来处理数据在线路上的传输. 然而,他们依靠 ConnectionSocketFactory接口来创建,初始化和连接Socket.HttpClient的使用者能够在运行时,提供应用程序特定的Socket初始化代码.PlainConnectionSocketFactory类是创建和初始化普通(未加密)套接字的默认工厂类. 创建一个套接字和连接到主机的过程是解耦的,以便连接操作被阻塞的时候套接字能够被关闭 Ht

《HttpClient官方文档》第六章 HTTP 缓存

第六章. HTTP缓存 6.1. 通用概念 HttpClient Cache 提供了用HttpClient(等效浏览器缓存的Java实现)来兼容HTTP / 1.1的缓存层.实现遵循责任链模式,HttpClient缓存的实现类可以替代默认无缓存的HttpClient;完全可以通过缓存实现的请求将不会触发实际的原始请求.在可以的情况下,使用GETs条件If-Modified-Since和/or If-None-Match请求头,会自动验证旧的缓存项.HTTP / 1.1缓存一般被设计成语义透明的,

《HttpClient 官方文档》第三章 HTTP 状态管理

通常 HTTP 被设计为无状态,面向请求/响应的协议,对于有一些逻辑相关的请求/响应交换的有状态会话没有特别的规定.正当 HTTP 协议越来越流行和被认可,越来越多之前没有打算使用它的系统,现在也开始为了应用程序而使用它.例如电子商务应用的内容传输.因此,支持 HTTP 状态管理变得非常有必要. NetScape(网景公司),曾经引领网页客户端和服务器端软件的发展,在他们的产品中基于专有的规范,提供了 HTTP 状态管理的支持.之后,NetScape 尝试通过发布规范草案来标准化这种机制.这些努

《HttpClient官方文档》1.3 HTTP执行上下文

1.3 HTTP执行上下文 HTTP起初是被设计成一种无状态的.面向请求和响应的协议.然而实际的应用经常需要在请求-响应切换过程中保存状态信息.为了使应用能够维持处理状态,HttpClient允许HTTP请求可以在一个特殊的上下文环境(HttpContext)中执行.如果一个context在连续的HTTP请求中被复用,那么这些逻辑相关的请求可以参与到同一个逻辑会话中.HttpContext功能与java.util.Map<String, Object>类似,它是一组任意值的集合.一个应用程序可

《HttpClient官方文档》1.2 HttpClient 接口

1.2. HttpClient 接口 HttpClient 接口表示最基本的HTTP请求执行要约.它不会对请求执行过程加上约束或一些特定的信息,并且保留连接管理,状态管理,认证和处理重定向的细节到各自的实现中.这会使它更方便的使用额外功能来装饰接口,如响应内容缓存. 通常来说, HttpClient接口的实现负责处理特定方面的HTTP协议,比如重定向.身份认证处理.对连接的持久性和维持连接存活长短的决策之类的多个处理程序和策略接口实现的门面. 这使得用户能够有选择性的将一些自定义的,基于特定应用

《HttpClient官方文档》2.3 HTTP连接管理

2.3. HTTP 连接管理 2.3.1. 管理连接和连接管理器 HTTP 连接是复杂的. 有状态的. 非线程安全的对象,因此需要恰当的管理才能正常工作.HTTP连接一次只能由一个线程使用.HttpClient使用实现了HttpClientConnectionManager接口,被称为HTTP连接管理器的特殊实体去访问HTTP连接. HTTP连接管理器的作用是作为一个工厂类来为新的HTTP连接使用,管理持久连接的生命周期和同步访问,确保一次只能由一个线程使用连接. HTTP连接管理器内部与Man

《HttpClient官方文档》1.1 执行请求(二)

1.1.4. HTTP 实体 HTTP 消息可以携带与其相关联的请求或响应的内容实体.实体可以在一些请求和响应中找到,因为它们也是可选的.使用了实体的请求被称为封闭实体请求.HTTP规范定义了两种封闭实体的方法: POST 和PUT.响应通常期望包含一个内容实体. 这个规则也有特例,就像HEAD 方法和 204 No Content,304 Not Modified, 205 Reset Content 响应. HttpClient根据其内容来源以此区分三种类型的实体: streamed(流式)