Solr
  1. Solr
  2. SOLR-1872

Document-level Access Control in Solr

    Details

    • Type: New Feature New Feature
    • Status: Reopened
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.4
    • Fix Version/s: None
    • Labels:
    • Environment:

      Solr 1.4

      Description

      This issue relates to providing document-level access control for Solr index data.

      A related JIRA issue is: SOLR-1834. I thought it would be best if I created a separate JIRA issue, rather than tack on to SOLR-1834, as the approach here is somewhat different, and I didn't want to confuse things or step on Anders' good work.

      There have been lots of discussions about document-level access in Solr using LCF, custom comoponents and the like. Access Control is one of those subjects that quickly spreads to lots of 'ratholes' to dive into. Even if not everyone agrees with the approaches taken here, it does, at the very least, highlight some of the salient issues surrounding access control in Solr, and will hopefully initiate a healthy discussion on the range of related requirements, with the aim of finding the optimum balance of requirements.

      The approach taken here is document and schema agnostic - i.e. the access control is independant of what is or will be in the index, and no schema changes are required. This version doesn't include LDAP/AD integration, but could be added relatively easily (see Ander's very good work on this in SOLR-1834). Note that, at the moment, this version doesn't deal with /update, /replication etc., it's currently a /select thing at the moment (but it could be used for these).

      This approach uses a SearchComponent subclass called SolrACLSecurity. Its configuration is read in from solrconfig.xml in the usual way, and the allow/deny configuration is split out into a config file called acl.xml.

      acl.xml defines a number of users and groups (and 1 global for 'everyone'), and assigns 0 or more <acl-allow> and/or <acl-deny> elements.
      When the SearchComponent is initialized, user objects are created and cached, including an 'allow' list and a 'deny' list.
      When a request comes in, these lists are used to build filter queries ('allows' are OR'ed and 'denies' are NAND'ed), and then added to the query request.

      Because the allow and deny elements are simply subsearch queries (e.g. <acl-allow>somefield:secret</acl-allow>, this mechanism will work on any stored data that can be queried, including already existing data.

      Authentication
      One of the sticky problems with access control is how to determine who's asking for data. There are many approaches, and to stay in the generic vein the current mechanism uses http parameters for this.
      For an initial search, a client includes a username=somename parameter and a hash=pwdhash hash of its password. If the request sends the correct parameters, the search is granted and a uuid parameter is returned in the response header. This uuid can then be used in subsequent requests from the client. If the request is wrong, the SearchComponent fails and will increment the user's failed login count (if a valid user was specified). If this count exceeds the configured lockoutThreshold, no further requests are granted until the lockoutTime has elapsed.
      This mechanism protects against some types of attacks (e.g. CLRF, dictionary etc.), but it really needs container HTTPS as well (as would most other auth implementations). Incorporating SSL certificates for authentication and making the authentication mechanism pluggable would be a nice improvement (i.e. separate authentication from access control).

      Another issue is how internal searchers perform autowarming etc. The solution here is to use a local key called 'SolrACLSecurityKey'. This key is local and [should be] unique to that server. firstSearcher, newSearcher et al then include this key in their parameters so they can perform autowarming without constraint. Again, there are likely many ways to achieve this, this approach is but one.

      The attached rar holds the source and associated configuration. This has been tested on the 1.4 release codebase (search in the attached solrconfig.xml for SolrACLSecurity to find the relevant sections in this file).

      I hope this proves helpful for people who are looking for this sort of functionality in Solr, and more generally to address how such a mechanism could ultimately be integrated into a future Solr release.

      Many thanks,
      Peter

      1. ASF.LICENSE.NOT.GRANTED--SolrACLSecurity.java
        26 kB
        Peter Sturge
      2. ASF.LICENSE.NOT.GRANTED--SolrACLSecurity.java
        25 kB
        Peter Sturge
      3. SolrACLSecurity.rar
        19 kB
        Peter Sturge

        Issue Links

          Activity

          Hide
          Peter Sturge added a comment - - edited

          This update adds in optional auditing of searches by users and failed access attempts, plus a few minor tweaks.

          To configure auditing, here is a sample searchComponent section from solrconfg.xml:

            <searchComponent name="SolrACLSecurity" class="org.apache.solr.handler.security.SolrACLSecurity">
                <!-- SolrACLSecurityKey can be any alphanumeric string, the more complex the better.
                     For production environments, don't use the default value - create a new value.
                     This property needs to be present in all firstSearcher and newSearcher warming queries, otherwise
                     those requests will be blocked.
                -->
                <str name="SolrACLSecurity">zxb79j3g76A79N8N2AbR0K852976qr1klt86xv436j2</str>
                <str name="config-file">acl.xml</str>
                <!-- Auditing: Set audit to true to log all searches, including failed access attempts -->
                <bool name="audit">true</bool>
                <int name="maxFileSizeInMB">10</int>
                <int name="maxFileCount">10000</int>
                <str name="auditFile">audit.log</str>
                <!-- 
                      User lockout 
                      'lockoutThreshold' is the number of consecutive incorrect logins before locking out the account
                      'lockoutTime' is the number of minutes to lockout the account
                      If 'lockoutThreshold' is 0 or less, account lockout is disabled (no accounts are ever locked out)
                      If not specified, the default values are: lockThreshold=5 lockoutTIme=15
                -->
                <str name="lockoutThreshold">5</str>
                <str name="lockoutTime">15</str>
           </searchComponent>
          
          Show
          Peter Sturge added a comment - - edited This update adds in optional auditing of searches by users and failed access attempts, plus a few minor tweaks. To configure auditing, here is a sample searchComponent section from solrconfg.xml: <searchComponent name= "SolrACLSecurity" class= "org.apache.solr.handler.security.SolrACLSecurity" > <!-- SolrACLSecurityKey can be any alphanumeric string, the more complex the better. For production environments, don't use the default value - create a new value. This property needs to be present in all firstSearcher and newSearcher warming queries, otherwise those requests will be blocked. --> <str name= "SolrACLSecurity" >zxb79j3g76A79N8N2AbR0K852976qr1klt86xv436j2</str> <str name= "config-file" >acl.xml</str> <!-- Auditing: Set audit to true to log all searches, including failed access attempts --> <bool name= "audit" > true </bool> < int name= "maxFileSizeInMB" >10</ int > < int name= "maxFileCount" >10000</ int > <str name= "auditFile" >audit.log</str> <!-- User lockout 'lockoutThreshold' is the number of consecutive incorrect logins before locking out the account 'lockoutTime' is the number of minutes to lockout the account If 'lockoutThreshold' is 0 or less, account lockout is disabled (no accounts are ever locked out) If not specified, the default values are: lockThreshold=5 lockoutTIme=15 --> <str name= "lockoutThreshold" >5</str> <str name= "lockoutTime" >15</str> </searchComponent>
          Hide
          Peter Sturge added a comment -

          Updates a typo or two plus some misc tweaks.

            <searchComponent name="SolrACLSecurity" class="org.apache.solr.handler.security.SolrACLSecurity">
                <!-- SolrACLSecurityKey can be any alphanumeric string, the more complex the better.
                     For production environments, don't use the default value - create a new value.
                     This property needs to be present in all firstSearcher and newSearcher warming queries, otherwise
                     those requests will be blocked.
                -->
                <str name="SolrACLSecurityKey">zxb79j3g76A79N8N2AbR0K852976qr1klt86xv436j2</str>
                <str name="config-file">acl.xml</str>
                <!-- Auditing: Set audit to true to log all searches, including failed access attempts -->
                <bool name="audit">true</bool>
                <int name="maxFileSizeInMB">10</int>
                <int name="maxFileCount">10000</int>
                <str name="auditFile">audit.log</str>
                <!-- 
                      User lockout 
                      'lockoutThreshold' is the number of consecutive incorrect logins before locking out the account
                      'lockoutTime' is the number of minutes to lockout the account
                      If 'lockoutThreshold' is 0 or less, account lockout is disabled (no accounts are ever locked out)
                      If not specified, the default values are: lockThreshold=5 lockoutTime=15
                -->
                <str name="lockoutThreshold">5</str>
                <str name="lockoutTime">15</str>
            </searchComponent>  
          

          Thanks,
          Peter

          Show
          Peter Sturge added a comment - Updates a typo or two plus some misc tweaks. <searchComponent name= "SolrACLSecurity" class= "org.apache.solr.handler.security.SolrACLSecurity" > <!-- SolrACLSecurityKey can be any alphanumeric string, the more complex the better. For production environments, don't use the default value - create a new value. This property needs to be present in all firstSearcher and newSearcher warming queries, otherwise those requests will be blocked. --> <str name= "SolrACLSecurityKey" >zxb79j3g76A79N8N2AbR0K852976qr1klt86xv436j2</str> <str name= "config-file" >acl.xml</str> <!-- Auditing: Set audit to true to log all searches, including failed access attempts --> <bool name= "audit" > true </bool> < int name= "maxFileSizeInMB" >10</ int > < int name= "maxFileCount" >10000</ int > <str name= "auditFile" >audit.log</str> <!-- User lockout 'lockoutThreshold' is the number of consecutive incorrect logins before locking out the account 'lockoutTime' is the number of minutes to lockout the account If 'lockoutThreshold' is 0 or less, account lockout is disabled (no accounts are ever locked out) If not specified, the default values are: lockThreshold=5 lockoutTime=15 --> <str name= "lockoutThreshold" >5</str> <str name= "lockoutTime" >15</str> </searchComponent> Thanks, Peter
          Hide
          Alexander Roethinger added a comment -

          Hello Peter,

          I have a few detailed questions regarding your component.
          Is there any way to get in touch with you directly?

          Kind regards
          Alexander

          Show
          Alexander Roethinger added a comment - Hello Peter, I have a few detailed questions regarding your component. Is there any way to get in touch with you directly? Kind regards Alexander
          Hide
          Arvind Das added a comment -

          Hii there
          Does this work in solr 3.4 ? I am using solr 3.4 and want to apply document level security. Or should I use ManifoldCF ?
          I found it a bit simpler. Please tell if it can be applied else I think there is no alternative than ManifoldCF.
          Thanks in advance

          Show
          Arvind Das added a comment - Hii there Does this work in solr 3.4 ? I am using solr 3.4 and want to apply document level security. Or should I use ManifoldCF ? I found it a bit simpler. Please tell if it can be applied else I think there is no alternative than ManifoldCF. Thanks in advance
          Hide
          Peter Sturge added a comment -

          Hi,

          I've not yet tried it directly with 3.4, but as it's a subclass of
          SearchComponent, it should work fine.
          Since it is just a plugin, it's easy to add it in via your solrconfig.xml.

          Peter

          On Fri, Dec 30, 2011 at 10:03 AM, Arvind Das (Commented) (JIRA)

          Show
          Peter Sturge added a comment - Hi, I've not yet tried it directly with 3.4, but as it's a subclass of SearchComponent, it should work fine. Since it is just a plugin, it's easy to add it in via your solrconfig.xml. Peter On Fri, Dec 30, 2011 at 10:03 AM, Arvind Das (Commented) (JIRA)
          Hide
          Erick Erickson added a comment -

          2013 Old JIRA cleanup

          Show
          Erick Erickson added a comment - 2013 Old JIRA cleanup

            People

            • Assignee:
              Unassigned
              Reporter:
              Peter Sturge
            • Votes:
              1 Vote for this issue
              Watchers:
              13 Start watching this issue

              Dates

              • Created:
                Updated:

                Development