Question

I have a .NET Web Application that acts as a front-end site for users, and this application leverages a separate SharePoint 2013 Application to serve data to the users. One of the tasks was to implement Search on the front end by leveraging SharePoint's own search. I solved this problem by writing my Search queries using server side code.

The problem I'm encountering is that although search results are returned correctly, there is no security trimming on them. For example, if I have 2 documents, Document A and Document B, and I have a user who can only access Document A, a search by the user still returns both documents. After some research, I figured that this might be due to the way I create my search query, but so far I haven't been able to find a solution to the problem. Here is the code that creates the Search Query

// Get the result source and the search service proxy
string resultSourceName = ConfigurationManager.AppSettings["ResultSourceName"];

SearchServiceApplicationProxy searchProxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(spSite));
FederationManager federationManager = new FederationManager(searchProxy);
SearchObjectOwner searchOwner = new SearchObjectOwner(SearchObjectLevel.Ssa, spSite.RootWeb);
Microsoft.Office.Server.Search.Administration.Query.Source resultSource = federationManager.GetSourceByName(resultSourceName, searchOwner);

// Create a query object, set its result source and set the properties to return in the search results table
KeywordQuery query = new KeywordQuery(spSite);
query.SourceId = resultSource.Id;

I have two questions:

  1. What is the problem with the above code that is causing this security trimming issue?
  2. If it is not the code, what are the other possible causes of this issue?
Was it helpful?

Solution 2

I finally found the solution to the problem. Thanks to Mike Lutge for pointing me in the right direction.

The funny thing is that although spSite.UserToken and spSite.RootWeb.CurrentUser both reference the user performing the search query, the search still seems to be run using the System Account context. I believe that the either the KeywordQuery or SearchExecutor class ignores the user in the spSite and runs it automatically as the system account. To force it to impersonate the user, I used this code to create the spSite:

System.Security.Principal.WindowsIdentity w = ((System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity);

using (WindowsImpersonationContext ctx = w.Impersonate())
using (SPSite spSite = new SPSite(ConfigurationManager.AppSettings["TheSPSite"]))
{
    response = searchRequest.searchFunction(searchRequest, spSite);
}

This allows me to run the search queries with the correct security trimming on them.

OTHER TIPS

If the code you have posted above is running in a SharePoint 2013 app then in order for your search query to be executed as the user you will need to add the following to your AppManifest.xml:

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/search" Right="QueryAsUserIgnoreAppPrincipal" />
</AppPermissionRequests>
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top