首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Apache HttpClient 4进行抢占式基本身份验证

使用Apache HttpClient 4进行抢占式基本身份验证
EN

Stack Overflow用户
提问于 2010-01-07 01:05:46
回答 10查看 75.9K关注 0票数 53

是否有比上述here更简单的方法来设置http客户端以进行抢占式基本身份验证

在以前的版本(3.x)中,它过去是一个简单的方法调用(例如,httpClient.getParams().setAuthenticationPreemptive(true))。

我想要避免的主要事情是将BasicHttpContext添加到我执行的每个方法中。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2010-08-16 21:49:21

在每次不传递上下文的情况下很难做到这一点,但是您可以使用请求拦截器来做到这一点。下面是我们使用的一些代码(可以从他们的JIRA,iirc中找到):

// Pre-emptive authentication to speed things up
BasicHttpContext localContext = new BasicHttpContext();

BasicScheme basicAuth = new BasicScheme();
localContext.setAttribute("preemptive-auth", basicAuth);

httpClient.addRequestInterceptor(new PreemptiveAuthInterceptor(), 0);

(...)

static class PreemptiveAuthInterceptor implements HttpRequestInterceptor {

    public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
        AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);

        // If no auth scheme avaialble yet, try to initialize it
        // preemptively
        if (authState.getAuthScheme() == null) {
            AuthScheme authScheme = (AuthScheme) context.getAttribute("preemptive-auth");
            CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
            HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
            if (authScheme != null) {
                Credentials creds = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
                if (creds == null) {
                    throw new HttpException("No credentials for preemptive authentication");
                }
                authState.setAuthScheme(authScheme);
                authState.setCredentials(creds);
            }
        }

    }

}
票数 23
EN

Stack Overflow用户

发布于 2010-12-02 04:20:33

如果您希望强制HttpClient 4使用单个请求进行身份验证,则可以使用以下方法:

String username = ...
String password = ...
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);

HttpRequest request = ...
request.addHeader(new BasicScheme().authenticate(creds, request));
票数 88
EN

Stack Overflow用户

发布于 2012-08-08 23:31:48

这与Mat的Mannion的解决方案相同,但您不必将localContext放到每个请求中。它更简单,但它为所有请求添加了身份验证。如果您不能控制单个请求,就像我在使用Apache Solr时一样,它在内部使用HttpClient时很有用。

import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

httpClient.addRequestInterceptor(new PreemptiveAuthInterceptor(), 0);

(...)

static class PreemptiveAuthInterceptor implements HttpRequestInterceptor {

    public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
        AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);

        // If no auth scheme available yet, try to initialize it
        // preemptively
        if (authState.getAuthScheme() == null) {
            CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
            HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
            Credentials creds = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
            if (creds == null) {
                throw new HttpException("No credentials for preemptive authentication");
            }
            authState.setAuthScheme(new BasicScheme());
            authState.setCredentials(creds);
        }

    }

}

当然,您必须设置凭据提供者:

httpClient.getCredentialsProvider().setCredentials(
                new AuthScope(url.getHost(), url.getPort()),
                new UsernamePasswordCredentials(username, password))

AuthScope不能包含realm,因为它事先是未知的。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2014700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档