I need a search request handler that only return a specific sets of field in a collection, but for security reasons, no one can change what fields to be displayed. (There are some indexed sensitive fields that I don't want anyone access it)
I tried to use invariants in the request handler, and define the list of field there, so I made a handler like this:
<requestHandler class="solr.SearchHandler" name="/search">
<lst name="defaults">
<str name="q">*:*</str>
</lst>
<lst name="invariants">
<str name="fl">content</str>
<str name="fl">description</str>
</lst>
</requestHandler>
However, I get this error when I call the request handler:
{
"responseHeader":{
"zkConnected":true,
"status":500,
"QTime":4},
"error":{
"trace":"java.lang.NullPointerException\r\n\tat org.apache.solr.handler.component.QueryComponent.mergeIds(QueryComponent.java:940)\r\n\tat org.apache.solr.handler.component.QueryComponent.handleRegularResponses(QueryComponent.java:585)\r\n\tat org.apache.solr.handler.component.QueryComponent.handleResponses(QueryComponent.java:564)\r\n\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:423)\r\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:177)\r\n\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:2503)\r\n\tat org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:710)\r\n\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:516)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:382)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:326)\r\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1751)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\r\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)\r\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\r\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\r\n\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)\r\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\r\n\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\r\n\tat org.eclipse.jetty.server.Server.handle(Server.java:534)\r\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)\r\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)\r\n\tat org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:251)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)\r\n\tat org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)\r\n\tat java.lang.Thread.run(Unknown Source)\r\n",
"code":500}}
Currently I do a workaround to put the fields inside the default instead of invariants. so I made the handler to be like this instead:
<requestHandler class="solr.SearchHandler" name="/search">
<lst name="defaults">
<str name="q">*:*</str>
<str name="fl">content</str>
<str name="fl">description</str>
</lst>
</requestHandler>
This workaround is working, but I don't want that because it's not secure enough. Anyone can help? For additional information, I'm using Solr version 7.2.1, and the collection has 2 shards, 2 replicas.
When you set the fl
list to invariant
, that means that the internal requests between shards won't be able to override it either. The line triggering your error is:
resultIds.put(shardDoc.id.toString(), shardDoc);
I'm guessing you'd want to include id
in your field list, and probably _version_
and _root_
as well. _version_
have special meaning when it comes to replication and optimistic concurrent update, while _root_
affects child documents.