4

I am building a Sitecore 8.1 / Solr 4.10 site. I want to be able to do a general site content query through the web database and only return content items that the current user has permissions to view. To me this seems like a simple request and should be a no-brainer. However we never figured this out properly. So we built what seems like a convoluted solution where we have 2 different custom fields in our Solr index - one called read_roles that is a list of all of the roles that have read access to the indexed item. And another called denied_roles that is a list of all of the roles that do not have read access to the indexed item. Then in our search method we apply a security filter using the following code:

public static IQueryable<T> ApplySecurityFilter<T>(this IQueryable<T> query) where T : SearchResultItem {

    var userRoles = Sitecore.Context.User.Roles.Select(r => r.Name);

    var readPredicate = PredicateBuilder.False<T>();
    readPredicate = userRoles.Aggregate(readPredicate, (current, role) => current.Or(i => i["read_roles"].Equals(role)));

    var denyPredicate = PredicateBuilder.True<T>();
    denyPredicate = userRoles.Aggregate(denyPredicate, (current, role) => current.And(i => !i["denied_roles"].Equals(role)));

    if (readPredicate.Body.NodeType != System.Linq.Expressions.ExpressionType.Constant) {
        query = query.Filter(readPredicate);
    }
    if (readPredicate.Body.NodeType != System.Linq.Expressions.ExpressionType.Constant) {
        query = query.Filter(denyPredicate);
    }
    return query;
}

This seemed to work in Sitecore v7.5 but now I am having trouble in Sitecore 8.1. Is there some simpler way of restricting the results in a Solr query to only be items that the current user has read access to?

Corey

2

If you enable security via the SearchSecurityOptions in the CreateSearchContext checking the access rights should be done for you. Although I have heard that the TotalResults property is not ok when doing is and items are filtered out - also heard that paging might not be accurate. But the result set should be ok.

More info also here.

Adding security information inside the index is tempting but very tricky. Security on an item can be changed in so many ways (user changes role, inheritance is broken on a parent, language security changes...) that it is very difficult to keep all the information up to date (without rebuilding the index each time).

| improve this answer | |
  • Yeah we are doing that, but it doesn't seem to work. We are definitely using the SearchSecurityOptions when we create the search context. And yet the results that we get do not match what we see when we use Access Viewer. Frustrating. – Corey Burnett Oct 18 '16 at 20:34
  • That's weird. I have seen it working, but that was not on a 8.1 though. Are you sure the query is not in some sort of SecuritySwitcher or Disabler? – Gatogordo Oct 18 '16 at 20:36
  • So here's a follow up question then. If I am using the SearchSecurityOptions when I create my context should I be able to see something different in the query that gets sent to Solr that is in the Sitecore Search log? In other words will there be something that I can see in the query that shows that Sitecore is specifying the user in the query that gets sent to Solr? – Corey Burnett Oct 18 '16 at 21:28
  • No, you won't. The security is not checked by Solr but by a filter which is applied afterwards. That is probably the reason why the results are ok, but things like TotalResults are not. – Gatogordo Oct 19 '16 at 4:19
  • Ok - thanks. That makes sense. So that is why we tried to roll our own solution. If TotalResults doesn't work properly, then what is the point of using the SearchSecurityOptions? We have a requirement that we have to be able to display the total number of results. Seems amazing to me that a product like Sitecore can't get something as simple as "search using security" to work properly. – Corey Burnett Oct 19 '16 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.