[ 
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-unsubscr...@solr.apache.org
For additional commands, e-mail: issues-h...@solr.apache.org

Reply via email to