为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

肥皂起泡泡 2019-08-12 18:06:14
使用Apache HttpClient进行抢占式基本身份验证4是否有一种更简单的方法来设置http客户端以进行抢先式基本身份验证,而不是此处描述的内容?在以前的版本(3.x)中,它曾经是一个简单的方法调用(例如httpClient.getParams().setAuthenticationPreemptive(true))。我想避免的主要是将BasicHttpContext添加到我执行的每个方法。
查看完整描述

3 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

如果没有每次传递上下文都很难做到这一点,但你可以通过使用请求拦截器来做到这一点。这是我们使用的一些代码(从他们的JIRA,iirc中找到):

// Pre-emptive authentication to speed things upBasicHttpContext 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);
            }
        }

    }}


查看完整回答
反对 回复 2019-08-12
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

如果您希望强制HttpClient 4通过单个请求进行身份验证,则以下内容将起作用:

String username = ...String password = ...UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);HttpRequest request = ...request.addHeader(new BasicScheme().authenticate(creds, request));


查看完整回答
反对 回复 2019-08-12
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

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

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不能包含的境界,因为它是事先不知道。


查看完整回答
反对 回复 2019-08-12
  • 3 回答
  • 0 关注
  • 781 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信