【问题标题】:Preemptive Authentication with HttpClient 4.3 and Solr 5使用 HttpClient 4.3 和 Solr 5 的抢先式身份验证
【发布时间】:2015-07-08 09:23:26
【问题描述】:

我尝试使用此类 https://subversion.jfrog.org/jfrog/build-info/trunk/build-info-client/src/main/java/org/jfrog/build/client/PreemptiveHttpClient.java 和 Solr 为 Basic Auth 保护的 Solr 进行 PreEmptive Authentication,但这些方法已被弃用,所以我不知道这是否是一个问题。在 Solr 中查询的情况很好,但是对于索引我在与服务器交谈时发生 IOException:example.com:8983/solr/core1。

HttpSolrClient 构造函数需要一个 httpClient 作为参数来执行抢先授权,因此对于上面的类,因为 httpClient 存储在一个私有变量中,所以我在该变量上使用了一个 getter 来获取 httpClient 并传递给 HttpSolrClient 构造函数。也不确定我是否做对了。

PreemptiveAuthenticate preemp = new PreemptiveAuthenticate("username", "password", 1);
    DefaultHttpClient httpClient = preemp.getHttpClient();
    System.out.println("Made it to connectSolr after set Authentication");
    SolrClient solr = new HttpSolrClient(urlString, httpClient);

我知道像 http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html Example 4.6 这样的示例可以使用 HttpClient 4.3 进行抢先授权,但这是一个测试用例,我看不到通过 HttpClient 进行抢先身份验证的方法。

【问题讨论】:

    标签: solr httpclient basic-authentication preemptive


    【解决方案1】:

    修复 Paulius 的代码,HttpClient 4.3 的抢占式身份验证。在需要连接 Solr 时调用 createHttpClient 的类中创建方法。

    public static HttpClient createHttpClient(String username, String password) {
        if (username == null) {
            username = "";
        }
        if (password == null) {
            password = "";
        }
        HttpClientBuilder clientBuilder = HttpClientBuilder.create();
    
        BasicCredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
    
        clientBuilder.setDefaultCredentialsProvider(provider);
        clientBuilder.addInterceptorFirst(new PreemptiveAuthInterceptor());
        return clientBuilder.build();
    }
    
    static class PreemptiveAuthInterceptor implements HttpRequestInterceptor {
        @Override
        public void process (HttpRequest request, HttpContext context) throws HttpException {
            AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
            if (authState.getAuthScheme() == null) {
                CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);
                HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
                Credentials credentials = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
                if (credentials == null) {
                    throw new HttpException("No credentials provided for preemptive authentication.");
                }
                authState.update(new BasicScheme(), credentials);
            }
        }
    }
    

    【讨论】:

    • 太棒了!也适用于 solrj 6.5.0 和 CloudSolrClient!例如:CloudSolrClient.Builder scb = new CloudSolrClient.Builder(); scb.withHttpClient("您的自定义 HTTPCLIENT"); CloudSolrClient solr_client = scb.withZkHost("ZK_ADDRESS").build();
    • 这比文档好。文档提供的唯一 2 个解决方案是为每个请求设置它,并且您不能使用典型的辅助方法,如 query() 或 update()。或者设置并不总是方便的复杂系统属性。为什么我们在 SolrClient/Builder 上没有一个简单的 API (setBasicAuth(x,y))?这感觉应该是一行,使用自动完成找到它,完成。不阅读大量文档和 stackoverflow 帖子来解决随机问题。
    【解决方案2】:

    你必须像这样创建 HttpClient:

    public static HttpClient createHttpClient(String username, String password) {
        if (username == null) {
            username = "";
        }
        if (password == null) {
            password = "";
        }
        HttpClientBuilder clientBuilder = HttpClientBuilder.create();
    
        BasicCredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
    
        clientBuilder.setDefaultCredentialsProvider(provider);
        clientBuilder.addInterceptorFirst((HttpRequest request, HttpContext context) -> {
            AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
            if (authState.getAuthScheme() == null) {
                CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);
                HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
                Credentials credentials = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
                if (credentials == null) {
                    throw new HttpException("No credentials provided for preemptive authentication.");
                }
                authState.update(new BasicScheme(), credentials);
            }
        });
        return clientBuilder.build();
    }
    

    然后你必须把它交给 solr 服务器,你的请求将被抢先验证。

    【讨论】:

    • 这看起来像是更新版本的最佳代码,但我收到错误测试 addInterceptorFirst 参数似乎错误,它说它接受 HttpRequestInterceptor
    猜你喜欢
    • 2011-01-02
    • 2011-02-16
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多