0

I am writing a console app for the purpose of a remote timer job that is using the high trust app only add-in model to access SharePoint by using a certificate. This is test code I created for this example. The add-in works fine using certificates to log in. I only see unexpected behavior when running a search query. So for this example I am not providing all code.

I have 3 test sitecollections in my farm (test1, test2 and test3) When I execute this regular CSOM I get all the sites in my console:

        using (ClientContext clientContext = new ClientContext("http://test.local/test/site1"))
        {
            KeywordQuery query = new KeywordQuery(clientContext);
            query.QueryText = "Path:\"http://test.local/test/*\" AND ContentClass:STS_Site";
            query.RowLimit = 500;//max row limit is 500 for KeywordQuery
            query.SelectProperties.Add("Url");
            query.TrimDuplicates = false;
            SearchExecutor searchExecutor = new SearchExecutor(clientContext);
            ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(query);
            clientContext.ExecuteQuery();


            foreach (var item in results.Value[0].ResultRows)
            {
                Console.WriteLine(item["Url"].ToString());
            }
        }

Output:

Now I have this code snippet (I am using a certificate to connect)

        using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity("http://test.local/test/site1", currentUserWindowsIdentity))
        {
            KeywordQuery query = new KeywordQuery(clientContext);
            query.QueryText = "Path:\"http://test.local/test/*\" AND ContentClass:STS_Site";
            query.RowLimit = 500;//max row limit is 500 for KeywordQuery
            query.SelectProperties.Add("Url");
            query.TrimDuplicates = false;
            SearchExecutor searchExecutor = new SearchExecutor(clientContext);
            ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(query);
            clientContext.ExecuteQuery();
        }

The output in this case is only sitecollection 1

Any ideas why I get only 1 result? The add in has full control persmissions on all three sitecollections. When I change the url:

        using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity("http://test.local/test/site2", currentUserWindowsIdentity))

I only see:

as the result

Update

When I use the root sitecollection url like:

        using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity("http://test.local", currentUserWindowsIdentity))

I do get all the three sites. Is this expected behaviour?

Update

When searching in the sitecollections through the searchbox I get all sitecollections in my result.

0

This could have something to do with the Search Result Source or "Search Scope" for each site collection being specific to itself, whereas the "root" site collection has a scope that defines all site collections.

If you go to the site collections themselves and perform a query via the interface, do you see the same behaviour?

If so, you could probably update the search result source/scope to include all site collections like the root has.

  • When I paste the same query in my searchbox in one off the three sitecollections I see all three sitecollections. I see no differences in my Search Result Sources between root site and the three test sitecollections – Danny Jul 16 '18 at 8:07
  • When I don't use my custom search result page but the builtin /_layouts/15/osssearchresults.aspx the parameter u is passed and then I don't see all sitecollections from test1..3. I do see all when on the root sitecollection When I remove the u parameter I see all from test1..3 – Danny Jul 16 '18 at 8:34
  • Nevermind, I see your 2nd last update mentions it working from the root. And I'm not certain if this is expected. It might be injecting the "u" parameter in transit. Maybe inspect the http request with Wireshark to see the final query URL – Chad Jul 16 '18 at 15:49
0

I ended up giving the App principal full control on my tenant with this powershell script.

$absoluteWebApplicationUrl = https://localhost

    if(-not $absoluteWebApplicationUrl.EndsWith('/')) {
        $absoluteWebApplicationUrl = "$absoluteWebApplicationUrl/"
}

$AppName = "Provider Placeholder App"
$clientID = "bfeae944-65cb-4335-9ce4-7c024183c465"  
$authRealm = Get-SPAuthenticationRealm -ServiceContext $absoluteWebApplicationUrl;
$AppIdentifier = $clientID  + '@' + $authRealm;

Register-SPAppPrincipal -NameIdentifier $AppIdentifier -Site $absoluteWebApplicationUrl -DisplayName $AppName | Out-Null
Write-Verbose "     *App Registered" -Verbose

$appPrincipal = Get-SPAppPrincipal -NameIdentifier $AppIdentifier -Site $absoluteWebApplicationUrl
if($null -ne $appPrincipal) {
    #Remove-SPAppPrincipalPermission -appPrincipal $appPrincipal -site $absoluteWebApplicationUrl -Scope Site
    Remove-SPAppPrincipalPermission -Site $absoluteWebApplicationUrl -AppPrincipal $appPrincipal -Scope SiteSubscription   | Out-Null
    Write-Verbose "     *App Trust Removed" -Verbose
}

#Set-SPAppPrincipalPermission -Site $absoluteWebApplicationUrl -AppPrincipal $appPrincipal -Scope Site -Right FullControl -EnableAppOnlyPolicy | Out-Null
Set-SPAppPrincipalPermission -Site $absoluteWebApplicationUrl -AppPrincipal $appPrincipal -Scope SiteSubscription -Right FullControl -EnableAppOnlyPolicy | Out-Null    
Write-Verbose "     *App Trust Added" -Verbose

The -Scope parm is key. Setting this to SiteSubscription gives the principal full control on the webapplication. In my case all the site collections on my webapp. In my case I can do this. For setting the permissions per site collection use -scope SiteCollection or -scope site

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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