Solr Query Returns no Documents when Executed with a Non-Privileged User

With a default secure collection configuration, you might have noticed that even if your user has the full set of Sentry privileges to access a particular collection, there are no documents returned for queries executed by the user, but executing the same query with the Solr superuser (solr by default) gives the expected results.

Why this Happens:

Starting with CDH 6, the default secure templates for solrconfig.xml, in addition to the collection level security, also enable the Solr document level security. For more information, see Providing Document-Level Security Using Sentry. You can verify this by looking at the solrconfig.xml of your collection and verifying whether it has the QueryDocAuthorizationComponent enabled:
<searchComponent name="queryDocAuthorization" class="org.apache.solr.handler.component.QueryDocAuthorizationComponent" >
     <!-- Set to true to enabled document-level authorization -->
     <bool name="enabled">true</bool>
     <!-- Field where the auth tokens are stored in the document -->
     <str name="sentryAuthField">sentry_auth</str>
     <!-- Auth token defined to allow any role to access the document.
          Uncomment to enable. -->
     <!--<str name="allRolesToken">*</str>-->
   </searchComponent>

This article uses an example with a hypothetical systest user, belonging to a group which has the my_role Sentry role assigned, granting access to the collection 'myTestCollection'.

If you add a document to 'myTestCollection' as the systest user:
kinit systest
curl -k --negotiate -u : -X POST 'https://mysolrserver-1.example.com:8985/solr/myTestCollection/update?wt=json' -H 'content-type: application/json' -d '[{"id":"1","title":"My document without access token defined"}]'
The add operation is successful, but whenever you query the collection, this document is not returned among search results.

What to Do:

You may choose one of the following options to make the queries working as expected:
  • Leave the document level security enabled, and whenever inserting a document, specify the role that will be able to query that document.
  • Leave document level security enabled, and also enable the All Roles Token.
  • Disable document level security and rely only on collection level security.

Leaving the Document Level Security Enabled, and Specifying the Role Able to Query a Document at Insertion

You may opt for leaving document level security enabled and specifying the role that will be able to query a given document at insertion time.

When document level security is enabled, each document stores a field which specifies the roles that are able to query that particular document. In the default configuration this field is called sentry_auth. If you add a new document to this Solr collection where the sentry_auth field of this document has the value 'my_role', only the users who have the Sentry role 'my_role' will get this document returned in any search results.

kinit systest
curl -k --negotiate -u : -X POST 'https://mysolrserver-1.example.com:8985/solr/myTestCollection/update?wt=json' -H 'content-type: application/json' -d '[{"id":"19","title":"My document accessible by my_role", "sentry_auth":"my_role"}]'

Since the systest user in the example is in a group which has the role my_role, the recently added document is successfully retrieved:

curl -k --negotiate -u : "https://mysolrserver-1.example.com:8985/solr/myTestCollection/select?q=:"
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":18,
    "params":{
      "q":"*:*",
      "doAs":"systest"}},
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"19",
        "title":["My document accessible by myrole"],
        "_version_":1616957635311960064}]
  }}

Leaving Document Level Security Enabled and Enabling the All Roles Token

The document level security feature also allows defining a token (called the allRolesToken) which allows any role to access a particular document which has this token in the sentryAuthField specified. If in the solrconfig.xml file you uncomment the line <str name="allRolesToken">*</str> it results in all Sentry roles being able to query all documents that are submitted with the sentry_auth field value set to *.
<searchComponent name="queryDocAuthorization" class="org.apache.solr.handler.component.QueryDocAuthorizationComponent" >
     <!-- Set to true to enabled document-level authorization -->
     <bool name="enabled">true</bool>
     <!-- Field where the auth tokens are stored in the document -->
     <str name="sentryAuthField">sentry_auth</str>
     <!-- Auth token defined to allow any role to access the document.
          Uncomment to enable. -->
     <!--<str name="allRolesToken">*</str>-->
   </searchComponent>
This option enables you to specify for individual documents that all users can access them, regardless of roles.
  1. Modify the solrconfig.xml of your collection and uncomment: <str name="allRolesToken">*</str>
  2. After updating the solrconfig.xml, do a reload operation on the collection (In this example: solrctl collection --reload myTestCollection).
  3. You can now add a document with setting the sentry_auth field to the defined allRolesToken (*):
    kinit systest
    curl -k --negotiate -u : -X POST 'https://mysolrserver-1.example.com:8985/solr/myTestCollection/update?wt=json' -H 'content-type: application/json' -d '[{"id":"20","title":"My document with allRolesToken", "sentry_auth":"*"}]'
Do a query with the systest user:
kinit systest
curl -k --negotiate -u : "https://mysolrserver-1.example.com:8985/solr/myTestCollection/select?q=:"

It returns two documents (id 19 had the sentry_auth set to my_role which is the Sentry role associated with the systest user and id 20 which has sentry_auth set to * which is 'any roles')

"response":{"numFound":2,"start":0,"docs":[
      {
        "id":"19",
        "title":["My document accessible by myrole"],
        "_version_":1616957635311960064},
      {
        "id":"20",
        "title":["My document with allRolesToken"],
        "_version_":1616958682453508096}]

Disabling Document Level Security and Relying Only on Collection Level Security

This option means that whoever has a Sentry role giving access to a collection will be able to access all documents in that collection. To implement this option:

  1. Locate the following entry in solrconfig.xml:
    <searchComponent name="queryDocAuthorization" class="org.apache.solr.handler.component.QueryDocAuthorizationComponent" >
  2. Change
    <bool name="enabled">true</bool>
    to
    <bool name="enabled">false</bool>
  3. Update the instance configuration. Update and reload the collection configuration.

Repeat the query and it returns all documents in the collection (The document with id 1 did not have a value for the sentry_auth field, meaning that no one was able to query it, however you have disabled document level security and use collection level security only, so the systest user who has access to the collection will now get all documents in that collection):

kinit systest
curl -k --negotiate -u : "https://mysolrserver-1.example.com:8985/solr/myTestCollection/select?q=:"
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":7,
    "params":{
      "q":"*:*",
      "doAs":"systest"}},
  "response":{"numFound":3,"start":0,"docs":[
        {
          "id":"1",
          "title":"My document without access token defined",
          "_version_":1616949033619685376},
        {
          "id":"19",
          "title":"My document accessible by myrole",
          "_version_":1616957635311960064},
        {
          "id":"20",
          "title":"My document with allRolesToken",
          "_version_":1616958682453508096}]
  }}