none
How to create a "none security trimmed" result source? RRS feed

  • Question

  • Hi,

    I am implementing a "site finder" that lets all people in the company search for sites and sub sites. Basically, no matter if they have access or not, I want users to be able to search and se all sites and sub sites in the search result.

    I tried to create a custom result source and was able to the the filtering down (not that hard...) but I just can't get it to stop security trim the results. Basically, I only get results back that the current user have access to.

    I was under the impression that you could specifiy an "common" account that all queries would be "run-as" and as long as the account had read-access to all sites (like for example the crawl account) I should be fine. Am I wrong to think that this should work? What am I missing here?  

    Cheers,

    CJ

    Code for my result source is:

              Microsoft.SharePoint.SPServiceContext context = SPServiceContext.GetContext(site);
                   // Get the search service application proxy
                   SearchServiceApplicationProxy searchProxy = context.GetDefaultProxy(typeof(SearchServiceApplicationProxy)) as SearchServiceApplicationProxy;
                   // Get the search service application info object so we can find the Id of our Search Service App
                   SearchServiceApplicationInfo ssai = searchProxy.GetSearchServiceApplicationInfo();
                   // Get the application itself
                   SearchServiceApplication application = Microsoft.Office.Server.Search.Administration.SearchService.Service.SearchApplications.GetValue<SearchServiceApplication>(ssai.SearchServiceApplicationId);
    
                   FederationManager fedManager = new FederationManager(application);
                   SearchObjectOwner owner = new SearchObjectOwner(SearchObjectLevel.SPSite, site.RootWeb);
                   Source currentResultSource = fedManager.CreateSource(owner);
                   currentResultSource.Name = "Site Catalogue";
                   currentResultSource.AuthInfo = new AuthenticationInformation(FederationAuthType.ApplicationPoolIdentity); //Needs to update?
                   Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties QueryProperties = new Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties();
                   currentResultSource.CreateQueryTransform("{SearchBoxQuery} contentclass:STS_Site contentclass:STS_Web Path:" + searchPath); 
                   currentResultSource.ProviderId = fedManager.ListProviders()["Local SharePoint Provider"].Id;
                   currentResultSource.Commit();

    Tuesday, November 19, 2013 6:05 PM

All replies

  • Use SPSecurity.RunWithElevatedPrivileges

    Scott Brickey
    MCTS, MCPD, MCITP
    www.sbrickey.com

    Tuesday, November 19, 2013 6:28 PM
  • Hi,

    Not sure when? When I create the result source? From a UI perpective I am using standard searchbox/search result web parts so I am not executing my query inside any "custom code". I was hoping I could tell the result source to take care if this. I.e. always providing me the "full" result set. Any suggestions?

       

    Tuesday, November 19, 2013 6:33 PM
  • Hi,

    I don't think it is possible. SharePoint does search results security trimming based on current user identity. This is by design. Using result source you can trim them more but you can't extend results. 

    I guess this may work: if you have a page on each site/sub site which is opened to everyone it suppose to be presented  in search results. You can drop web part on that page which redirect user to default page of this web (in code behind you could even check if it is real user or crawler). This is just an idea only - I've never tried it. Would be interesting to know if that worked if you go that way.

    Regards,

     


    Vladimir
    MCP, MCTS, SharePoint tips blog: http://buyevich.blogspot.com

    Tuesday, November 19, 2013 8:59 PM
  • I think the best option for you will be to create a custom web part that shows all the sites in your farm, and then redirect them to a query page with the "Path:<siteurl>" set.  Then they would see any items based on that site. 

    Refiners are built based on the results that are returned.  Obviously, if they don't have access, then it won't be in the result set, and no refiners will be built.


    Chris Givens CEO, Architecting Connected Systems Blog Twitter

    Sunday, December 1, 2013 7:40 PM
  • A simpler option would be to use powershell to populate and update a sharepoint list that contains all of your sites. Then crawl that using a custom search refiner and display template. Or use a content query web part to display and search them.

    My CodePlex - My Blog - My Twitter
    Join me at the San Francisco SharePoint User Group!

    If this post helped you or answered your question please remember to mark it! :)

    Sunday, December 1, 2013 11:22 PM
  • For those with the same issue, I did find the solution. This is the code (as a feature)

    The key was to create a SA level Result Source that uses a common account. Once created, I just updated the RS to run as the crawl account and voila! 

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    
    {
    
      
    
    
    SPSite site = properties.Feature.Parent as SPSite;
    
                   
    
    
    String searchPath = site.Url + "*";
    
                   Microsoft.SharePoint.
    
    
    SPServiceContext context = SPServiceContext.GetContext(site);
    
                   
    
    
    // Get the search service application proxy
    
            
    
    
    SearchServiceApplicationProxy searchProxy = context.GetDefaultProxy(typeof(SearchServiceApplicationProxy)) as SearchServiceApplicationProxy;
    
                   
    
    
    // Get the search service application info object so we can find the Id of our Search Service App
    
    
                   
    
    
    SearchServiceApplicationInfo ssai = searchProxy.GetSearchServiceApplicationInfo();
    
                   
    
    
    // Get the application itself
    
    
                   
    
    
    SearchServiceApplication application = Microsoft.Office.Server.Search.Administration.SearchService.Service.SearchApplications.GetValue<SearchServiceApplication>(ssai.SearchServiceApplicationId);
    
                   
    
    
    FederationManager fedManager = new FederationManager(application);
    
                   
    
    
    SearchObjectOwner owner = new SearchObjectOwner(SearchObjectLevel.Ssa);
    
                   
    
    
    string sourceName = "Site Catalogue - "  + searchPath;
    
                   
    
    
    Source s = fedManager.GetSourceByName(sourceName, owner);
    
                   
    
    
    if (s != null)
    
                   {
    
                       fedManager.RemoveSource(s);
    
                   }
    
                   
    
    
    Source currentResultSource = fedManager.CreateSource(owner);
    
                   currentResultSource.Name = sourceName;
    
                   
    
    
    AuthenticationInformation authInfo = new AuthenticationInformation(FederationAuthType.SingleAccountNTLM);
    
                   currentResultSource.AuthInfo = authInfo;
    
                   Microsoft.Office.Server.Search.Query.Rules.
    
    
    QueryTransformProperties QueryProperties = new Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties();
    
                   currentResultSource.CreateQueryTransform(
    
    
    "{SearchBoxQuery} contentclass:STS_Site contentclass:STS_Web Path:" + searchPath); 
    
                   currentResultSource.ProviderId = fedManager.ListProviders()[
    
    
    "Local SharePoint Provider"].Id;
    
                   currentResultSource.Commit();
    
     
    
            }
    

    Monday, December 2, 2013 8:58 PM