While we generally lock down features many months before we get to RTM and spend all of the remaining time on performance and stability, there are a few – very few – number of times when we find we really have to squeeze in one more feature at the last minute. It happened with the RTM release of Microsoft Office SharePoint Server, and it required the cooperation of both the Search team and the team that works on the Business Data Catalog. The feature? Support for custom query time trimming of search results.

You know how we can trim search results so users only see links to items they can actually open? That works great today as long as the content source being indexed could serialize the Access Control Lists for each item we'd index. When that works, we actually record the ACL in the index at index gather (a.k.a., crawl) time. And since we know who you are when you execute a search, we'd just compare your userid/group memberships to those in the ACL and either display or not display the search result accordingly.

But what do you do when the content source in question can't serialize its ACLs (e.g., a normal Web site), has a completely different approach to security (LOB systems), or can't serialize ACLs in a way we'd be able to make sense of them (some third-party content repository with its own user/group management)?

I'll tell you what you do. You create a component that implements the ISecurityTrimmer interface. We'll call its Initialize() function once and then hit it with one or more calls to the CheckAccess() function, passing you URLs and context info. Your job is to call whatever code you have to call for each of these URLs and return to us a bitarray that tell us which URLs can be viewed by this user. We'll keep calling CheckAccess() until we build up enough results to fill a page (or until you set a flag that tells us you want us to stop).

This is all documented in the SDK that became available for download today at http://msdn.microsoft.com/office/sharepoint. Search for "Custom Security Trimming" and it will all fall into place.

Now, this would be great by itself, but the BDC gang did their part as well. There's a BDC Custom Security Trimmer in the box. As long as the application definition XML file has an Entity with a Method with a MethodInstance of type "AccessChecker", we'll use it for custom trimming purposes.

Before someone says it in comments, of course this can have an impact on query-time performance. How much will depend on your LOB system's API performance and the ration of results to authorized results. But the alternatives are (a) don't search repositories that don't provide ACLs at index gathering time, (b) don't worry about security on search results of such data, or (c) create a custom protocol handler for searching such sources and have it incorporate a security mapping layer of some kind that translates the back-end system's security model into something that looks like NTFS ACLs. Me, I'd take the tiny hit and reap the massive benefits J.

I'll work on getting an example of both a custom trimming component and a BDC application definition that references an AccessChecker method posted to GotDotNet, and when I do, I'll post links here.

More postings on integration topics to follow. Yes, I'm back and blogging up a storm for a while…