Sites.Selected is an application permission granted to Azure AD apps, addressing a significant limitation that previously existed. Granting permissions such as Sites.Read.All and Sites.ReadWrite.All in an Azure AD app would apply those permissions to all sites in the tenant, which contradicts the security principle of least privileged access. Informed developers understood the implications and refrained from requesting such permissions, and even tenant administrators would reject such requests. This functionality was available in legacy SharePoint provider-hosted apps, where developers could register their apps on a specific site’s appregnew.aspx and grant application permissions limited to that particular site through appinv.aspx. However, considering the recommendation to use Azure AD Apps, this limitation needed to be addressed by Microsoft and they released the functionality. Official documentation here – https://devblogs.microsoft.com/microsoft365dev/controlling-app-access-on-specific-sharepoint-site-collections/ and recent blog from support team https://techcommunity.microsoft.com/t5/microsoft-sharepoint-blog/develop-applications-that-use-sites-selected-permissions-for-spo/ba-p/3790476
I will share my experience working with it in this blog post.
First step is to add the permission “Sites.Selected” under Microsoft Graph to an Azure AD app that will use Microsoft Graph API to access SharePoint site. We have “Sites.Selected” under SharePoint also, this is used if SharePoint REST API/CSOM used to access SharePoint sites. This post doesn’t cover that, that’s for later.
The next step involves granting the Azure AD app or service principal the required access to specific site(s). This can be achieved using different methods. Here are a few options that have been tried and tested:
- Graph Explorer: If the Graph Explorer app is already available or the administrator is willing to add it to the tenant, this provides a straightforward approach. By utilizing Graph Explorer, you can make API calls to assign the necessary permissions to the Azure AD app/service principal on the desired site(s).
- Graph PowerShell SDK: This method leverages the “Microsoft Graph Command Line Tools” enterprise app rather than Graph Explorer. Using the Graph PowerShell SDK, you can automate the process of granting access to specific site(s) for the Azure AD app/service principal.
- PnP PowerShell SDK: In this approach, the “PnP Management Shell” is utilized instead of the aforementioned enterprise apps. The PnP PowerShell SDK enables the management of SharePoint operations, including granting access to selected site(s) for the Azure AD app/service principal.
In all of these methods, the fundamental requirement is to have an Azure AD app with the “Sites.FullControl.All” permission, granted either as delegated or application permission by the administrator. Additionally, you can create a custom Azure AD app registration with the necessary permission to accomplish the same goal.
4. Create new Azure AD App registration with the same permission “mentioned above”Sites.FullControl.All”.
So far, we have ensured that we have the necessary app registration and permissions in place to grant access to the first Azure AD app with the “Sites.Selected” permission to a specific SharePoint site. By ensuring the availability of the required app registration and obtaining the necessary permission, we have set the stage for granting the desired access to the selected SharePoint site(s) for the first Azure AD app. Now we will see how its done.
Graph Explorer or custom Azure AD app
The Graph API endpoint ‘Create permission’ is used to grant an Azure AD application permission to access a SharePoint site. https://learn.microsoft.com/en-us/graph/api/site-post-permissions?view=graph-rest-1.0&tabs=http
Allowed Permissions – [read|write|manage|fullcontrol]
POST https://graph.microsoft.com/v1.0/sites/{sitesId}/permissions
Content-Type: application/json
{
"roles": ["write"],
"grantedToIdentities": [{
"application": {
"id": "[Azure AD App Client Id]",
"displayName": "Test Sites.Selected"
}
}]
}
Graph PowerShell SDK
$ErrorActionPreference = 'Stop'
# INPUTS
$appId = "[Azure AD App Client Id]"
$appDisplayName = "Test Sites.Selected"
$siteId = "[Site GUID]"
$permission = "read"
# CONNECT
Connect-MgGraph -Scopes "Sites.Read.All","Sites.FullControl.All"
# TEST - Get Current Permissions
Write-Host "Before the update" -ForegroundColor Green
$permissions = Get-MgSitePermission -SiteId $siteId
$permissions | Select-Object -ExpandProperty GrantedToIdentities | Select-Object -ExpandProperty Application
# ADD - new Service Principal
$body = @{
'roles' = @(
$permission
);
'grantedToIdentities' = @(
@{
'application' = @{
'id' = $appId
'displayName' = $appDisplayName
}
}
);
}
$bodyJson = $body | ConvertTo-Json -Depth 10 -Compress
Invoke-MgGraphRequest `
-Method POST `
-Uri "v1.0/sites/$siteId/permissions" `
-Body $bodyJson
# TEST - Get Updated Permissions
Write-Host "After the update" -ForegroundColor Green
$permissions = Get-MgSitePermission -SiteId $siteId
$permissions | Select-Object -ExpandProperty GrantedToIdentities | Select-Object -ExpandProperty Application
PnP PowerShell SDK
Connect-PnPOnline -Url https://[tenant].sharepoint.com/sites/[sitename] -Interactive
Grant-PnPAzureADAppSitePermission -AppId '[Azure AD App Client ID]' -DisplayName '[Azure AD App Display Name]' -Site 'https://[tenant].sharepoint.com/sites/[sitename]' -Permissions Read
You can now proceed to test various operations on the SharePoint site, such as reading or writing SharePoint list items, depending on the specific permission granted to the Azure AD application.
Unlocking Hidden Power: Granting Permissions via appinv.aspx – An Alternative Approach
As a bonus, there is an interesting option available for granting permissions to an Azure AD application on a SharePoint site. This option is not documented by Microsoft, so it’s important to exercise caution and make decisions based on your own discretion.
The appinv.aspx page is a SharePoint legacy feature that allows you to grant permissions to SharePoint provider-hosted apps. Although it is not officially documented by Microsoft, some developers have explored its usage for granting permissions to Azure AD applications as well.
To utilize the appinv.aspx page, you can follow these steps:
- Navigate to the SharePoint site where you want to grant permissions to the Azure AD application.
- Append “/_layouts/15/appinv.aspx” to the site URL, and access the appinv.aspx page.
- On the appinv.aspx page, you can specify the App Id of the Azure AD application that you want to grant permissions to.
- In the “Permission Request XML” field, you can define the specific permissions and their levels that you want to grant to the Azure AD application. The format for defining permissions follows the SharePoint permission schema. Sample xml below.
- Click the “Create” button to save the changes and grant the permissions to the Azure AD application.
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
</AppPermissionRequests>
For permissions xml you can check this documentation. https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azureacs
Indeed, one interesting aspect of utilizing the appinv.aspx approach is that it allows the site collection administrator to grant permissions directly on the SharePoint site. Unlike the other approaches that involve using an Azure AD app with “Sites.FullControl.All” permission, which requires admin consent, this method provides an alternative option that does not rely on additional Azure AD apps or admin involvement.
By leveraging the appinv.aspx page, the site collection administrator can have more control over granting permissions to the Azure AD application without the need for external dependencies. This can be particularly useful in scenarios where administrative overhead or obtaining admin consent for additional Azure AD apps is not feasible or desirable.
However, it’s important to note that this approach is not officially documented by Microsoft and may have its own limitations and considerations. It’s recommended to thoroughly understand the implications and perform thorough testing before implementing it in a production environment.