In my last article we looked at SharePoint 2010 search service arhvcitecture and what’s involved in search results trimming. In this article we’ll take a look at how to write your custom security trimmer assembly.
1. Start by creating a Windows Assembly project in Visual Studio.
2. Ensure the following namespaces are referenced in your new class:
using Microsoft.Office.Server.Search.Administration;using System.Security.Principal;using System.Web;using System.Collections.Specialized;using System.Collections;using Microsoft.IdentityModel.Claims;using Microsoft.SharePoint.Administration.Claims;using Microsoft.Win32;
3. Our class will implement ISecurityTrimmer interface and will have the following methods defined:
public class MyTrimmer : ISecurityTrimmer2
{
public void Initialize(NameValueCollection staticProperties,
SearchServiceApplication searchApplication)
{
}
public BitArray CheckAccess(IList<String> crawledUrls,
IDictionary<String, Object> sessionProperties, IIdentity userIdentity)
{
}
private static string GetUsernameFromClaim(IIdentity userIdentity, string user)
{
}
private bool CheckUserAccess(string strUser)
{
}
}
Here, CheckUserAccess – is used to ensure the user that made the query has proper access to actually see the results. This method can be anything and depending on it we’ll trim out the results or not. GetUsernameFromClaim - will extract username from the claim (remember SharePoint 2010 uses claims for its security framework).
Here is our CheckAccess that will return an array of URLs and whether they are visible to a user or not based on what was determined in CheckUserAccess method:
public BitArray CheckAccess(IList<String> crawledUrls,IDictionary<String, Object> sessionProperties, IIdentity userIdentity){BitArray urlStatus = new BitArray(crawledUrls.Count, false);string user = string.Empty;user = GetUsernameFromClaim(userIdentity, user);if (string.IsNullOrEmpty(user)) return urlStatus;bool isAuthenticatedUser = this.CheckUserAccess(user);if (!isAuthenticatedUser){return urlStatus;}for (int i = 0; i < crawledUrls.Count; i++){urlStatus[i] = true;}return urlStatus;}
Our helper methods will look like this:
private static string GetUsernameFromClaim(IIdentity userIdentity, string user){IClaimsIdentity claimsIdentity = (IClaimsIdentity)userIdentity;if (claimsIdentity != null){foreach (Claim claim in claimsIdentity.Claims){if (SPClaimTypes.Equals(claim.ClaimType, SPClaimTypes.UserLogonName)){user = claim.Value;break;}}}return user;}private bool CheckUserAccess(string strUser){// this will probably connect to some resource// to verify whether the user has accessif (strUser.Equals("MyAccount")){return true;}else{return false;}}
Last but not least we’ll sing an assembly and drop it into GAC. In my next article – let’s take a look how you can deploy your trimmer with PowerShell.
… stay tuned.