Implementing security in Lucene

June 28th, 2010 by Silvester van der Bijl Leave a reply »

Lotus Notes has integrated search functionality but it’s limited. For this reason we’ve developed a custom, standalone, search application based on Apache Lucene. Already being used in production environments, we’re now implementing features as requested by our customers. Today’s feature: security using Domino groups. Read on to learn how we’ve implemented this in Lucene.

Background information

Because our application is called by the Domino server using plain HTTP, we don’t have access to the currently authenticated user. For this reason we rely on the Domino server to relay information about the group memberships of the current user, or the access privileges of the document we’re indexing. So basically we’re implementing a server side filter.

Storing access privileges

For every document that’s added or updated our application receives a POST request with information about the document. Among the information sent to us are the security groups that are allowed to access (READ) the document.

We don’t do any special processing on these fields (although there’s some talk about the case sensitivity of this solution), but just store the security groups as a multi valued field in the Lucene index:

1
2
3
for (String group : groups) {
  document.add(new Field("group", group, Field.Store.YES, Field.Index.NOT_ANALYZED));
}

Filtering results

Now for the fun part. Whenever a query is executed against our application (search, tags, related content, etc) we extract the current user’s groups (as specified by the Domino server) from a custom header and use this information to construct a TermFilter:

1
2
3
4
5
6
7
8
9
protected Filter createGroupFilter(String[] groups) {
  TermsFilter filter = new TermsFilter();
 
  for (String group : groups) {
    filter.addTerm(new Term("group").createTerm(group));
  }
 
  return filter;
}

Now for all queries we support, we filter the results using the filter defined above. This might look something like this:

1
2
IndexSearcher indexSearcher = new IndexSearcher(indexWriter.getReader());
TopDocs filteredResults = indexSearcher.search(query, createGroupFilter(groups), 100);

Conclusion

Of course there’s more to integrating security in our application than shown, but that’s out of scope for this blog. If you want to implement a security (or any type of) filter that’s executed server side in Lucene, this information might be of use to you.

Side note about our blogging habits

It’s been very quiet on our blog for a while. Because we do feel it’s important to tell you about the interesting and fun stuff we’re doing, yet somehow never seem to be able to find the time to actually write a blog or even tweet about it, we’ve decided to alter our definition of done. From now on a story can only be completed if we’ve blogged about it. If anything this should result in regular updates to this blog!

Advertisement

Trackbacks /
Pingbacks

  1. Lucene

Leave a Reply