Breaking role inheritance between Host Web and App Web

12.01.2018

Do you want the users to be able to control certain application on the SharePoint site while having only the lowest possible permissions on the site? SharePoint provides with flexible, though poorly documented approach which allows to break user role inheritance between Host Web and App Web and, thus, provide a control over only certain apps on the same SharePoint site.

HOST WEB AND APP WEB DEMYSTIFIED

Simply put, Host Web is the SharePoint site where an app is installed, while the same App is actually deployed to App Web - the site created underneath Host Web. Host Web is the site which all users have access to. App Web is the site which is used for administrative purposes. This model is available since SharePoint 2013.

Now, there is a problem – when you install SharePoint app, this app records user's settings, and therefore the user must have the permissions for editing in order to access the app (as you certainly had editing rights when installing the app). At the same time, you may want the users which access you Host Web to have read permissions only.

In order to provide an access to the app, while keeping read permissions on the site level, you need to break the role inheritance between Host Web and App Web. The solution below was tested on SharePoint online. An app it was tested on is WEATHER FORECAST. User settings are kept in SharePoint lists. So, the steps to break the role inheritance must be the following:

1. NAVIGATE TO APP PAGE (Site Contents -> App name)

2. OPEN WEB BROWSER DEV CONSOLE
(e.g. Click Console Tab (In Chrome)

3. LOAD JQUERY

var script = document.createElement("script");
script.setAttribute("src",
"https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js");
script.addEventListener('load', function() {
var script = document.createElement("script");
document.body.appendChild(script);
}, false);
document.body.appendChild(script);

4. BREAK INHERITANCE ON WEB LEVEL

$.ajax({ url:
"https://your_sp_site.sharepoint.com/_api/web/breakroleinheritance
(copyRoleAssignments = true, clearSubscopes = true)",
type: 'POST',
headers:{ "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val() },
success:function () { alert('success'); } ,
error: function (sender) { alert('error'); }
});

5. BREAK INHERITANCE ON LISTS LEVEL

$.ajax({ url:
"https://your_sp_site.sharepoint.com/_api/web/lists/getByTitle('Locations')/breakroleinheritance(copyRoleAssignments = true, clearSubscopes = true)",
type: 'POST',
headers:{ "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose", "X-RequestDigest": $("#__REQUESTDIGEST").val() },
success:function () { alert('success'); } ,
error: function (sender) { alert('error'); }
});
There are 2 lists in WEATHER FORECAST with settings.

$.ajax({ url:
"https://your_sp_site.sharepoint.com/_api/web/lists/getByTitle('Settings')/breakroleinheritance(copyRoleAssignments = true, clearSubscopes = true)", type: 'POST',
headers:{ "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose", "X-RequestDigest": $("#__REQUESTDIGEST").val() },
success:function () { alert('success'); } ,
error: function

6. ASSIGN PERMISSIONS (for both Weather Forecast aspp lists)

url: " https://your_sp_site.sharepoint.com/_api/web/lists/getByTitle('Locations')/roleassignments/addroleassignment(principalid=16,roleDefId=1073741830)", type: 'POST', headers:{ "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose", "X-RequestDigest": $("#__REQUESTDIGEST").val() }, success:function () { alert('success'); } , error: function (sender) { alert('error'); } }); $.ajax({

url: " https://your_sp_site.sharepoint.com/_api/web/lists/getByTitle('Settings')/roleassignments/addroleassignment(principalid=16,roleDefId=1073741830)", type: 'POST', headers:{ "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose", "X-RequestDigest": $("#__REQUESTDIGEST").val() }, success:function () { alert('success'); } , error: function (sender) { alert('error'); } });