Step 3 (Optional): Specify a Configurable Limit on the Number of Crawl URLs Checked

This walkthrough describes how to create, deploy and register a custom security trimmer for Enterprise Search in Microsoft Office SharePoint Server 2007 by using Microsoft Visual Studio 2005.

When you register a custom security trimmer with the stsadm utility, you can specify optional configuration properties with the registersecuritytrimmer operation. This supports creating a custom security trimmer with configurable settings.

For example, you could create a custom security trimmer with a configurable limit on the number of items checked by the security trimmer. While this is optional, we recommend that you include some type of limit in your custom security trimmer implementation. For more information, see Custom Security Trimming for Enterprise Search Results Overview.

Step 3 describes how to create and register a custom security trimmer with a configurable limit on the number of documents checked, and includes the following tasks:

  • Coding the custom security trimmer

  • Registering the custom security trimmer

The custom security trimmer described in this sample is similar to the one described in Step 1: Create the Custom Security Trimmer and Step 2: Deploy and Register the Custom Security Trimmer. In this custom security trimmer, however, we include additional steps to set a limit in the implementation, and change the stsadm utility command you use to register the custom security trimmer.

Coding the Custom Security Trimmer

Before starting the task described here, create the CustomSecurityTrimmer project and modify the CustomSecurityTrimmer class, as described in Step 1: Create the Custom Security Trimmer.

Note

This topic does not repeat steps already specified in Step 1 and 2; it only describes the tasks that are different. For information from the previous steps, see Step 1: Create the Custom Security Trimmer and Step 2: Deploy and Register the Custom Security Trimmer.

To code the custom security trimmer

  1. After you modify the class declaration to implement the ISecurityTrimmer interface, declare a variable for the limit value, as follows.

    class CustomSecurityTrimmer : ISecurityTrimmer
    {
        /*
           Sets a default limit of 200. You can change this 
           to a value that meets your specific requirements.
        */ 
        private int intCheckLimit = 200;
    
  2. Create a method to compare the number of items checked to the configured limit, add the following code.

    private bool CheckLimit(IDictionary<String, Object> sessionProperties, int numChecks)
    {
        Object currentCount;
        sessionProperties.TryGetValue("currentCheckCount", out currentCount);
        if (currentCount == null)
        {
            sessionProperties["currentCheckCount"] = numChecks;
            return (true);
        }
        int currentCountInt = Convert.ToInt32(currentCount);
        currentCountInt += numChecks;
        sessionProperties["currentCheckCount"] = currentCountInt;
        if (currentCountInt <= intCheckLimit)
        {
            return true;
        }
        else
        {
        return false;
        }
    }
    
  3. To complete the code for the custom security trimmer sample, you must modify the Initialize and CheckAccess method implementations described in Step 1: Create the Custom Security Trimmer.

To modify ISecurityTrimmer interface method implementations

  1. Add the following code to the Initialize method.

    if (trimmerProps["CheckLimitProperty"] != null)
    {
       intCheckLimit = Convert.ToInt32(trimmerProps["CheckLimitProperty"]);
    }
    

    This code sets the limit for the maximum number of documents that the security trimmer will check to the value of a configuration property named CheckLimitProperty.

    Note

    You can specify configuration properties when you register the security trimmer.

  2. Add the following code to the CheckAccess method, immediately after the method declaration.

    if (!this.CheckLimit(sessionProperties, crawlURLs.Count))
    {
        throw (new PluggableAccessCheckException("<Display Message>"));
    }
    

    This code calls the CheckLimit method. If the limit has been reached, this method returns false. When this occurs, a PluggableAccessCheckException exception is triggered, and the text specified in the PluggableAccessCheckException constructor—instead of the search results—is displayed in the search results user interface.

Registering the Custom Security Trimmer

Before you start this step, you must deploy CustomSecurityTrimmerSample.dll to the global assembly cache, as described in Step 2: Deploy and Register the Custom Security Trimmer. Then, you can register the custom security trimmer by using the stsadm utility.

The following procedure shows how to register a custom security trimmer with the ID set to 1 for the SharedServices1 Shared Services Provider (SSP), which is applied to content located on file shares for a server named FileServer1. It also sets the value of the CheckLimitProperty configuration setting to 300.

To register the custom security trimmer with the CheckLimitProperty configuration setting

  • At a command prompt, type the following command.

    stsadm -o registersecuritytrimmer -ssp SharedServices1 -id 1 -typeName "CustomSecurityTrimmerSample.clsCustomSecurityTrimmer, CustomSecurityTrimmerSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=<token>" -rulepath file://FileServer1/* -configprops CheckLimitProperty~300 
    

Example

Following is the complete sample code for the CustomSecurityTrimmerSample class described in this step.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Server.Search.Query;
using Microsoft.Office.Server.Search.Administration;
//For Windows Authentication
using System.Security.Principal;
//For Forms Authenticaion
using System.Web;
using System.Collections.Specialized;
using System.Collections;

namespace CustomSecurityTrimmerSample
{
    class CustomSecurityTrimmer : ISecurityTrimmer
    {
        private int intCheckLimit = 200;
        public void Initialize(NameValueCollection trimmerProps, SearchContext searchCxt)
        {
            if (trimmerProps["CheckLimit"] != null)
            {
                intCheckLimit = Convert.ToInt32(trimmerProps["CheckLimit"]);
            }
        }

        public BitArray CheckAccess(IList<String> crawlURLs, IDictionary<String, Object> sessionProperties)
        {
            BitArray retArray = new BitArray(crawlURLs.Count);
            if (!this.CheckLimit(sessionProperties, crawlURLs.Count))
            {
                throw (new PluggableAccessCheckException("Reached Limit"));
            }
        //For Windows authentication, uncomment the next line:
            //string strUser = WindowsIdentity.GetCurrent().Name;
        //For Forms authentication, uncomment the next line:
           //string strUser = HttpContext.Current.User.Identity.Name;
            for (int x = 0; x < crawlURLs.Count; x++)
            {
               /*
                Add code here to check if
                strUser can access crawlURLs[x]. 
                If so:
                retArray[x] = true;
                If not:
                retArray[x] = false;
              */
            }
            return retArray;
        }

        private bool CheckLimit(IDictionary<String, Object> sessionProperties, int numChecks)
        {
            Object currentCount;
            sessionProperties.TryGetValue("currentCheckCount", out currentCount);
            if (currentCount == null)
            {
                sessionProperties["currentCheckCount"] = numChecks;
                return (true);
            }
            int currentCountInt = Convert.ToInt32(currentCount);
            currentCountInt += numChecks;
            sessionProperties["currentCheckCount"] = currentCountInt;
            if (currentCountInt <= intCheckLimit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

See Also

Reference

Microsoft.Office.Server.Search.Query.ISecurityTrimmer
Microsoft.Office.Server.Search.Query.PluggableAccessCheckException

Concepts

Custom Security Trimming for Enterprise Search Results Overview
Walkthrough: Using a Custom Security Trimmer for Search Results
Step 1: Create the Custom Security Trimmer
Step 2: Deploy and Register the Custom Security Trimmer