Question

I got a problem and my brain says "yes you made no mistake" but it doesn't work. Here is my problem:

I have a SharePoint hosted App which has "Tenant read" permissions in the App Manifest.

App permissions are tenant read

That App has an AppPart which is installed on Site Collection A (on the root like http://mysharepoint.com/). I also have a SiteCollection B (like http://mysharepoint.com/sites/SiteCollectionB/) and in that Site Collection is a List. Now the App from Site Collection A wants to access Site Collection B with the Cross Site Scripting approach with JSOM. And I always get the typical "permission denied" message

Access denied. You do not have permission to perform this action or access this resource.

My Code for getting the context is written in TypeScript! Here is the part of the Code where I create the context and the web!

var appWebUrl: string = FuM.Helper.ParameterHelper.getWebAppUrl();
var targetWebUrl: string = "http://mysharepoint.com/sites/SiteCollectionB/";

context = new SP.ClientContext(appWebUrl);
var factory = new SP.ProxyWebRequestExecutorFactory(appWebUrl);
context.set_webRequestExecutorFactory(factory);
appContextSite = new SP.AppContextSite(context, targetWebUrl);

getListItemsAsync("Announcements", "", "", context, appContextSite.get_web())

and the code to get the list items

static getListItemsAsync(
        listTitle: string,
        camlQuery: string,
        include: string,
        clientContext: SP.ClientContext,
        targetWeb: SP.Web): JQueryPromise<SP.ListItemCollection> {

        var deferred = $.Deferred<SP.ListItemCollection>();

        var propertyList = targetWeb.get_lists().getByTitle(listTitle);

        var query = new SP.CamlQuery();

        if (camlQuery !== undefined && camlQuery !== '') {
            query.set_viewXml(camlQuery);
        }

        var listItems = propertyList.getItems(query);

        if (include !== undefined && include !== '') {
            clientContext.load(listItems, include);
        } else {
            clientContext.load(listItems);
        }

        clientContext.executeQueryAsync(
            () => { deferred.resolve(listItems); },
            (sender, args) => { FuM.Helper.LogHelper.logError(args); }
        );

        return deferred.promise();
    }

Does anyone see any mistake? Am I using the wrong urls to initialize or the wrong technique?

Was it helpful?

Solution

Disclaimer I haven't got any practical experience in tenant scoped apps but this is how I understood the article in MSDN

Even though the Scope is tenant but as mentioned, your app contains an APP Part. The msdn article mentions the following limitations of tenant-scoped apps:

The following kinds of apps cannot be batch-installed:

  1. Apps that contain a custom action for the ribbon. (Custom actions that are deployed as menu items are allowed
  2. Apps that contain an app part.
  3. In addition, note again that installation with tenant scope is not possible in the Office 365 Small Business Premium version of SharePoint Online.

When an App is installed in App catalog it is available for all websites in that Tenancy to be installed, when we install App on each Website manually it is web scoped and when it is installed as a batch to all websites specified in a tenancy it is a Tenant scope App. In tenancy scope it’s a single App Web shared across all Host Webs.

Hence in your case the app can access only the Host web where it is installed and nota different site collection.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top