In SharePoint 2013:

Imagine I have around 10 sites containing a document library and have created say 8 Active Directory security groups.
Visitor/read access for each site has been granted to one or two of the AD groups.

An AD user is a member of a number of these groups, to give them access to some of the libraries.

When a search is run as a given user, potential results will be from all of the libraries to which they have access. However, I have some business requirements that mean that I temporarily need to prevent the search from returning any results that are included as a result of the user's membership of one or two of the groups.


I'm attempting to use an ISecurityTrimmerPre to temporarily remove the user's claims to access some of the groups by setting up deny claims that mirror the incoming grant claims.

Unfortunately, my "deny" attempt doesn't seem to be denying any access. I still get results that shouldn't be included.

(The method on the custom trimmer that gets called is called "AddAccess", granted, but the return value is a tuple of a claim plus a boolean: false implies a grant claim and true a deny one, allegedly.)

Has anybody managed to successfully deny (pre-supplied) claims using an ISecurityTrimmerPre?

A few more details: The security trimmer is largely as per the one described here How to: Use a custom security trimmer for SharePoint Server search results except that to create the return value I'm pulling out the existing /groupsid claims and adding them as deny claims, roughly as:

List<Tuple<Microsoft.IdentityModel.Claims.Claim, bool>> claims = new List<Tuple<Microsoft.IdentityModel.Claims.Claim, bool>>();

        //Get all /groupsid: claims that aren't for the well-known Everyone group.

        var groups = claimsIdentity.Claims.Where(x => x.ClaimType != null && x.ClaimType.EndsWith("groupsid") && x.Value != null && (!(x.Value.Equals("S-1-1-0")))).ToList(); //Also catches  the primary groupsid

        if (removeEveryone == true)
            groups.AddRange(claimsIdentity.Claims.Where(x => x.ClaimType != null && x.ClaimType.EndsWith("/groupsid") && x.Value != null && ((x.Value.Equals("S-1-1-0")))).ToList()); 

        foreach (var group in groups)
            //Reverse every group member in groups!
            var newclaim = new Microsoft.IdentityModel.Claims.Claim(group.ClaimType, group.Value, group.ValueType, group.Issuer, group.OriginalIssuer);
            claims.Add(new Tuple<Microsoft.IdentityModel.Claims.Claim, bool>(newclaim, true));  //NB   TRUE IS A DENY CLAIM, THEY SAY!!!!

        return claims;

I've tried denying just select groups and, as above, I've tried denying all of them. I've tried denying all claims of any sort too. I've also tried using false instead of true. I've tried using the original claim object in the tuple as well as creating a new one with the same details. I've seen no change in the results (nor errors thrown) from any of these. I know my code is being executed in the search pipeline because I've successfully attached to the processes and stepped through it in the debugger. I'm trying this out in an AD authenticated environment, though it may need to be deployed in a claims-based one. (Should theoretically be able to get this working in an AD environment anyway, I'm figuring.)

Any ideas on the pre-trimmer? (Before I go with a post-trimmer attempt, which is obviously much less efficient and desirable...)

  • Trimmers are not always the best approach. I am struggling to understand the business case for the feature you are trying to implement. Can you add a comment explaining why you want to do this so I can try to come up with an alternate solution that would be more feasible in SharePoint? Mar 12 '14 at 12:08
  • Hi @MatthewMcDermott. Agreed they're not the best approach - but only because I can't get them to do what they seem to promise! I haven't given the whole picture above so I'll you give a little more (but there are limits to the changes I'm going to be allowed to make, so I was aiming for a solution within those): The search will be performed programmatically using the CSOM on behalf of a user. They are likely to have permissions (via AD groups, several inherited) to view more documents than they want to see at any given time. Effectively I need to offer them the option to ignore...
    – mwardm
    Mar 12 '14 at 14:34
  • permissions from some of the groups when they search.
    – mwardm
    Mar 12 '14 at 14:40
  • Why not limit the scope of their search with a result source rather than go through the hassle of custom development. Then once in the search results they could click a link to "Up Scope" and see all results? Mar 12 '14 at 20:46

Hmm. I've just found proof that a security pre trimmer won't work:

You cannot add a claim to match 'everyone' in a Windows SID terminology (by design, SID claims are not accepted from a pre-security trimmer).

courtesy of a comment in this MSDN blog.

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.