You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@solr.apache.org by "Mark Robert Miller (Jira)" <ji...@apache.org> on 2021/12/20 19:49:00 UTC

[jira] [Comment Edited] (SOLR-15237) Distributed search with index sharding is not working with basic authentication plugin enabled

    [ https://issues.apache.org/jira/browse/SOLR-15237?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17462811#comment-17462811 ] 

Mark Robert Miller edited comment on SOLR-15237 at 12/20/21, 7:48 PM:
----------------------------------------------------------------------

Okay, so some of that was assuming that all of the code in setupHttpClientForAuthPlugin made sense, but it's a bit of a stretch to say it does. It's also pretty wild to call pkiAuthenicationPlugin a plugin. It's not - it's essentially the security builder, which can delegate to plugins.

The code that looks scary to miss on a security.json update is:
{code:java}
if (authcPlugin instanceof HttpClientBuilderPlugin) {
  // Setup HttpClient for internode communication
  HttpClientBuilderPlugin builderPlugin = ((HttpClientBuilderPlugin) authcPlugin);
  SolrHttpClientBuilder builder = builderPlugin.getHttpClientBuilder(HttpClientUtil.getHttpClientBuilder());
  shardHandlerFactory.setSecurityBuilder(builderPlugin);
  updateShardHandler.setSecurityBuilder(builderPlugin);

  // The default http client of the core container's shardHandlerFactory has already been created and
  // configured using the default httpclient configurer. We need to reconfigure it using the plugin's
  // http client configurer to set it up for internode communication.
  log.debug("Reconfiguring HttpClient settings.");

  SolrHttpClientContextBuilder httpClientBuilder = new SolrHttpClientContextBuilder();
  if (builder.getCredentialsProviderProvider() != null) {
    httpClientBuilder.setDefaultCredentialsProvider(new CredentialsProviderProvider() {

      @Override
      public CredentialsProvider getCredentialsProvider() {
        return builder.getCredentialsProviderProvider().getCredentialsProvider();
      }
    });
  }
  if (builder.getAuthSchemeRegistryProvider() != null) {
    httpClientBuilder.setAuthSchemeRegistryProvider(new AuthSchemeRegistryProvider() {

      @Override
      public Lookup<AuthSchemeProvider> getAuthSchemeRegistry() {
        return builder.getAuthSchemeRegistryProvider().getAuthSchemeRegistry();
      }
    });
  }

  HttpClientUtil.setHttpClientRequestContextBuilder(httpClientBuilder);
} 
{code}

That is because the Kerbose plugin amoung others will hit that code path.

But in fact, the setSecurityBuilder calls in that block are irrelevant. The PKIAuthenticationPlugin will override them. So this just serves to 'init' those plugins with the call to 'builderPlugin.getHttpClientBuilder' as well as setup any Http 1 clients that may do internode communication. Are there any now? And how does that work with the correct behavior of the PKI impl allowing plugins to do internode else do it itself? I don't know. The comments around that code indicate it's not exactly been updated to the world of http2 clients in the shard handler.

So conceivably, there is no need to worry about responding to security updates and you just handling things as done in the patch - set the PKI security builder on the shard factory. But then that code block above should be cleaned up - it should not call the useless setSecurityBuilder methods. The comments should be updated to make sense. pkiAuthenticationPlugin should not masquerade as a plugin, and we should see if the HTTP 1 setup is actually required, and if so, how that works with the current PKI Auth is king security builder (not at all a plugin) design.


was (Author: markrmiller):
Okay, so some of that was assuming that all of the code in setupHttpClientForAuthPlugin made sense, but it's a bit of a stretch to say it does. It's also pretty wild to call pkiAuthenicationPlugin a plugin. It's not - it's essentially the security builder, which can delegate to plugins.

The code that looks scary to miss on a security.json update is:
{code:java}
if (authcPlugin instanceof HttpClientBuilderPlugin) {
  // Setup HttpClient for internode communication
  HttpClientBuilderPlugin builderPlugin = ((HttpClientBuilderPlugin) authcPlugin);
  SolrHttpClientBuilder builder = builderPlugin.getHttpClientBuilder(HttpClientUtil.getHttpClientBuilder());
  shardHandlerFactory.setSecurityBuilder(builderPlugin);
  updateShardHandler.setSecurityBuilder(builderPlugin);

  // The default http client of the core container's shardHandlerFactory has already been created and
  // configured using the default httpclient configurer. We need to reconfigure it using the plugin's
  // http client configurer to set it up for internode communication.
  log.debug("Reconfiguring HttpClient settings.");

  SolrHttpClientContextBuilder httpClientBuilder = new SolrHttpClientContextBuilder();
  if (builder.getCredentialsProviderProvider() != null) {
    httpClientBuilder.setDefaultCredentialsProvider(new CredentialsProviderProvider() {

      @Override
      public CredentialsProvider getCredentialsProvider() {
        return builder.getCredentialsProviderProvider().getCredentialsProvider();
      }
    });
  }
  if (builder.getAuthSchemeRegistryProvider() != null) {
    httpClientBuilder.setAuthSchemeRegistryProvider(new AuthSchemeRegistryProvider() {

      @Override
      public Lookup<AuthSchemeProvider> getAuthSchemeRegistry() {
        return builder.getAuthSchemeRegistryProvider().getAuthSchemeRegistry();
      }
    });
  }

  HttpClientUtil.setHttpClientRequestContextBuilder(httpClientBuilder);
} 
{code}

That is because the Kerbose plugin amount others will hit that code path.

But in fact, the setSecurityBuilder calls in that block are irrelevant. The PKIAuthenticationPlugin will override them. So this just serves to 'init' those plugins with the call to 'builderPlugin.getHttpClientBuilder' as well as setup and Http 1 clients that may do internode communication. Are there any now? And how does that work with the correct behavior of the PKI impl allowing plugins to do internode else do it itself? I don't know. The comments around that code indicate it's not exactly been updated to the world of http2 clients in the shard handler.

So conceivably, there is no need to worry about responding to security updates and you just handling things as done in the patch - set the PKI security builder on the shard factory. But then that code block above should be cleaned up - it should not call the useless setSecurityBuilder methods. The comments should be updated to make sense. pkiAuthenticationPlugin should not masquerade as a plugin, and we should see if the HTTP 1 setup is actually required, and if so, how that works with the current PKI Auth is king security builder (not at all a plugin) design.

> Distributed search with index sharding is not working with basic authentication plugin enabled
> ----------------------------------------------------------------------------------------------
>
>                 Key: SOLR-15237
>                 URL: https://issues.apache.org/jira/browse/SOLR-15237
>             Project: Solr
>          Issue Type: Bug
>          Components: Authentication
>    Affects Versions: 7.7.3, 8.7, 8.8.1
>            Reporter: Samir Huremovic
>            Assignee: Mark Robert Miller
>            Priority: Critical
>              Labels: Authentication
>
> Issue confirmed for 7.7.3, 8.7 and 8.8.1.
> Steps to reproduce are:
> 1. Following the docs for setting up distributed search (https://solr.apache.org/guide/8_8/distributed-search-with-index-sharding.html).
> 1.1 Stop both nodes after confirming that distributed search works without basic auth (last step).
> 2. Enable basic authentication plugin for both nodes, example for node1 {{example/nodes/node1/security.json}}:
> {noformat}
> "authentication":{ 
>    "blockUnknown": true, 
>    "class":"solr.BasicAuthPlugin",
>    "credentials":{"solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}, 
>    "realm":"My Solr users", 
>    "forwardCredentials": false 
> }}
> {noformat}
> 3. Configure {{shardsWhitelist}} in {{solr.xml}} for both nodes, example for node1 {{example/nodes/node1/solr.xml}}
> {noformat}
> <shardHandlerFactory name="shardHandlerFactory"
>     class="HttpShardHandlerFactory">
>     <int name="socketTimeout">${socketTimeout:600000}</int>
>     <int name="connTimeout">${connTimeout:60000}</int>
>     <str name="shardsWhitelist">localhost:8984,localhost:8985</str>
>   </shardHandlerFactory>
> {noformat}
> 4. Start both nodes.
> 5. Confirm that searching on one node with basic auth works with {{curl --user solr:SolrRocks "http://localhost:8984/solr/core1/select?q=*:*&wt=xml&indent=true"}}
> 6. Confirm that searching on both nodes does not work with {{curl --user solr:SolrRocks "http://localhost:8984/solr/core1/select?q=*:*&indent=true&shards=localhost:8985/solr/core1,localhost:8984/solr/core1&fl=id,name&wt=xml"}}
> Error:
> {noformat}
> ❯ curl --user solr:SolrRocks "http://localhost:8984/solr/core1/select?q=*:*&indent=true&shards=localhost:8985/solr/core1,localhost:8984/solr/core1&fl=id,name&wt=xml"
> <?xml version="1.0" encoding="UTF-8"?>
> <response>
> <lst name="responseHeader">
>   <int name="status">401</int>
>   <int name="QTime">173</int>
>   <lst name="params">
>     <str name="q">*:*</str>
>     <str name="shards">localhost:8985/solr/core1,localhost:8984/solr/core1</str>
>     <str name="indent">true</str>
>     <str name="fl">id,name</str>
>     <str name="wt">xml</str>
>   </lst>
> </lst>
> <lst name="error">
>   <lst name="metadata">
>     <str name="error-class">org.apache.solr.client.solrj.impl.BaseHttpSolrClient$RemoteSolrException</str>
>     <str name="root-error-class">org.apache.solr.client.solrj.impl.BaseHttpSolrClient$RemoteSolrException</str>
>   </lst>
>   <str name="msg">Error from server at null: Expected mime type application/octet-stream but got text/html. &lt;html&gt;
> &lt;head&gt;
> &lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8"/&gt;
> &lt;title&gt;Error 401 require authentication&lt;/title&gt;
> &lt;/head&gt;
> &lt;body&gt;&lt;h2&gt;HTTP ERROR 401 require authentication&lt;/h2&gt;
> &lt;table&gt;
> &lt;tr&gt;&lt;th&gt;URI:&lt;/th&gt;&lt;td&gt;/solr/core1/select&lt;/td&gt;&lt;/tr&gt;
> &lt;tr&gt;&lt;th&gt;STATUS:&lt;/th&gt;&lt;td&gt;401&lt;/td&gt;&lt;/tr&gt;
> &lt;tr&gt;&lt;th&gt;MESSAGE:&lt;/th&gt;&lt;td&gt;require authentication&lt;/td&gt;&lt;/tr&gt;
> &lt;tr&gt;&lt;th&gt;SERVLET:&lt;/th&gt;&lt;td&gt;default&lt;/td&gt;&lt;/tr&gt;
> &lt;/table&gt;
> &lt;/body&gt;
> &lt;/html&gt;
> </str>
>   <int name="code">401</int>
> </lst>
> </response>
> {noformat}
> See also SOLR-14569 that seems similar, but the patch provided does not help after I applied it to 8.8.1, therefore I think this is not the same issue.
> Adjust priority as necessary. For cases where basic auth is required this means we cannot use Solr as of now.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@solr.apache.org
For additional commands, e-mail: issues-help@solr.apache.org