1

I'm facing a problem with Search Server Express and Impersonation. I have an application which impersonate with user token and then launch a query by a KeywordQuery.

Suppose I have to impersonate the user USERX. I open site with the USERX Token so that I'm sure I'm impersonating it. If I do any operation this is logged as "USERX" (as write a new Item in a List) but if I search I get no results even if I have accessible items.

If I access from web interface and use the same query string search server returns me 30 results, so the problem is in the code or in the config...

Here is the simple code I'm trying to use:

 var user = //...GettingMySPUser with web.EnsureUser("i05...)
 var token = user.Token;

                using (SPSite scSite = new SPSite(fullsite, token))
                {
                    using (SPWeb webGroup = scSite.OpenWeb())
                    {
                        KeywordQuery keywordQuery = new KeywordQuery(scSite);

                        keywordQuery.ResultTypes = ResultType.RelevantResults;
                        keywordQuery.QueryText = "Cancellato:false";

                        ResultTableCollection searchResultTables = keywordQuery.Execute();
                        var searchResult = searchResultTables[ResultType.RelevantResults];

                        while (searchResult.Read())
                        {
                            string url = searchResult["Path"].ToString().Trim().ToLower();
     }
                    }
                }

2 Answers 2

1

Reading Technet and other sources it appears to be a well know issue.

The suggestion I can give to who is in my same problem is to implement a Custom Security trimmer: use the token to access file is working, only pass it to the claim is not.

So if you do a thing like:

  • Loop with SPRunWithElevatedPrivileges
  • Collect all results
  • Open a Site with User Token
  • Try to access every single result
  • If Can access => return it
  • If Cannot => do not
1

There is no need to write a custom trimmer as you can impersonate the user and query search as if you were her.

Helper classes:

public class WindowsImpersonation : IDisposable {

    public readonly bool impersonated = false;

    private WindowsImpersonationContext wic  = null;

    //upn is the user account in the form of [email protected]
    //ntAccount is not required but is used to prevent unnecessary impersonation
    public WindowsImpersonation(string upn, string ntAccount = "") {

        //see if impersonation is required
        WindowsIdentity current = WindowsIdentity.GetCurrent();
        if ( current != null && current.Name.Equals(ntAccount, StringComparison.OrdinalIgnoreCase) ) {
            return; //nope
        } 

        try {

            //
            // current user account must have the following permissions:
            //      - Act as Part of the Operating System
            //      - Impersonate a client after authentication
            //
            //  gpedit.msc -> local computer -> Windows Settings -> Security Settings -> Local Policies -> User Rights Assignment


            //impersonate user
            wic = (new WindowsIdentity(upn)).Impersonate();
            impersonated = true;
        } catch(Exception) {
            Dispose();
            throw;
        }

    }


    public void Dispose() {
        if (wic != null) {
            wic.Undo();
            wic = null;
        } 
    }

}

public static class Extensions_User_Impersonate {

     public static IDisposable Impersonate(this User user) {
         return new WindowsImpersonation(user.upn, user.ntAccount);
     }

}

Example:

//elevate, impersonate and search:
    //HostingEnvironment.Impersonate will not work in 2013.
SPSecurity.RunWithElevatedPrivileges(() => { 
    using (user.Impersonate()) {
        //Search code goes here
    }
});

(some associated classes not included and some comments redacted)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.