At line 1 changed one line |
!!!SharePoint Api permission: Sites.Selected\\ |
!!!Managing SharePoint Site Access for Applications Using Sites.Selected Permission\\ |
At line 3 changed one line |
__Sites.Selected__ permission gives the app access only to the specific SharePoint sites you authorize.\\ |
The __Sites.Selected__ permission allows an app to access only the specific SharePoint sites you explicitly authorize. This wiki page provides guidance on how to grant SharePoint write access (required for __SharePoint__/__SharePoint2 protocol__ see [SharePoint Integration]) to an __App Registration__ configured in the Azure Portal. Using Sites.Selected offers a much more secure alternative to granting full access across your entire tenant. See this: [https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread]\\ |
At line 5 added 288 lines |
!!__1.__ Create an App Registration with permission Sites.FullControl.All\\ |
\\ |
__!!! Important:__ This App Registration is not the working app that will access the SharePoint site. |
It is a helper/admin app, used only to configure and grant SharePoint write permissions to other apps (the real apps that will use Sites.Selected permission).\\ |
\\ |
Start at the Microsoft Azure portal: [https://azure.microsoft.com/en-us/features/azure-portal/]\\ |
\\ |
__Application registration:__ Navigate to App registrations in the Azure Portal. Click on __New registration__ to create a new application.\\ |
\\ |
[SharePoint%20Integration/new_registration.png]\\ |
\\ |
The __Redirect URI (optional)__ is not required, because it will has a __Application Permission__ only.\\ |
\\ |
__Configure API Permissions__: Navigate to API Permissions. Click on __Add a permission__ button. Select __Microsoft Graph__. Then select __Application Permission__. Search for __Sites__ and check the flag __Sites.FullControll.All__.\\ |
\\ |
[CrushTaskExample19/app_permission_sites_full_control.png]\\ |
\\ |
Grant __Admin consent__ for the newly added permission.\\ |
\\ |
[SharePoint Integration/app_permission_admin_consent.png]\\ |
\\ |
__Secret key__: A new client secret must be created. Go to Certificates & secrets, and generate a new client secret by clicking on New client secret. Ensure you copy over the value immediately!\\ |
\\ |
[SharePoint%20Integration/new_secret.png]\\ |
\\ |
[SharePoint%20Integration/secret_value.png]\\ |
\\ |
!!__2.__ Create an App Registration to Access Specific SharePoint Site Documents Using the Sites.Selected Permission\\ |
\\ |
Application registration: Go to the App registrations and click on New registration. Select platform: Web and Configure redirect URL like:\\ |
{{{ |
http://localhost:9090/register_microsoft_graph_api/ |
}}} |
or |
{{{ |
https://your.crushftp.domain.com/register_microsoft_graph_api/ |
}}} |
\\ |
Navigate to API Permissions. Click on Add a permission button. Select SharePoint or Microsoft Graph. Then select Delegated/Application Permission. Search for Sites and check the flag Sites.Selected.\\ |
\\ |
__2.1 App Permissions for SharePoint REST API__ (See at: [https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service?tabs=csom]):\\ |
\\ |
[CrushTaskExample19/app_permission_sharepoint_site_selected.png]\\ |
\\ |
__2.2 App Permissions for Microsoft Graph API__ (See at: [https://learn.microsoft.com/en-us/sharepoint/dev/apis/sharepoint-rest-graph]):\\ |
\\ |
[CrushTaskExample19/site_selected_microsoft_graph.png]\\ |
\\ |
Secret key: A new client secret must be created. Go to Certificates & secrets, and generate a new client secret by clicking on New client secret. Ensure you copy over the value immediately!\\ |
\\ |
!!! 3. How to Grant SharePoint Site Access to an App Registration Using the Microsoft Graph API?\\ |
\\ |
This is done by calling the __/permissions__ endpoint on the target SharePoint site. The request must include a valid Microsoft Graph access token with __Sites.FullControl.All__ application permission, and specify the App Registration you want to grant access to using the application.id in the request body:\\ |
{{{ |
POST https://graph.microsoft.com/v1.0/sites/{tenant}.sharepoint.com:/sites/{site-name}:/permissions |
|
BODY: { |
"roles": ["write"], |
"grantedToIdentities": [ |
{ |
"application": { |
"id": "11111111-2222-3333-4444-555555555555", |
"displayName": "My Azure App Registration" |
} |
} |
] |
} |
}}} |
\\ |
__Curl example__:\\ |
\\ |
{{{ |
curl -X POST "https://login.microsoftonline.com/<<App Registration: Directory (tenant) ID>>/oauth2/v2.0/token" \ |
-H "Content-Type: application/x-www-form-urlencoded" \ |
-d "client_id=XXX-XXXX-XXX-XX&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=XXX-XXXX-XXX-XX&grant_type=client_credentials" |
}}}\\ |
\\ |
{{{ |
curl -X POST "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/Your_Site:/permissions" \ |
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ |
-H "Content-Type: application/json" \ |
-d '{ |
"roles": ["write"], |
"grantedToIdentities": [ |
{ |
"application": { |
"id": "11111111-2222-3333-4444-555555555555", |
"displayName": "My Azure App Registration" |
} |
} |
] |
}' |
}}}\\ |
\\ |
__PowerShell example__:\\ |
{{{ |
$tenantId = "<<your-tenant-id>>" # Directory (tenant) ID |
$clientId = "XXX-XXXX-XXX-XX" # App Registration (client ID) |
$clientSecret = "XXX-XXXX-XXX-XX" # Client secret |
|
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" |
|
$body = @{ |
client_id = $clientId |
scope = "https://graph.microsoft.com/.default" |
client_secret = $clientSecret |
grant_type = "client_credentials" |
} |
|
$response = Invoke-RestMethod -Method POST -Uri $tokenEndpoint -Body $body -ContentType "application/x-www-form-urlencoded" |
|
# Output access token |
$accessToken = $response.access_token |
Write-Host "Access Token:" $accessToken |
}}}\\ |
\\ |
{{{ |
$accessToken = "YOUR_ACCESS_TOKEN" |
$sitePath = "contoso.sharepoint.com:/sites/Your_Site:" |
$uri = "https://graph.microsoft.com/v1.0/sites/$sitePath/permissions" |
|
$headers = @{ |
"Authorization" = "Bearer $accessToken" |
"Content-Type" = "application/json" |
} |
|
$body = @{ |
roles = @("write") |
grantedToIdentities = @( |
@{ |
application = @{ |
id = "11111111-2222-3333-4444-555555555555" |
displayName = "My Azure App Registration" |
} |
} |
) |
} | ConvertTo-Json -Depth 5 |
|
Invoke-RestMethod -Method POST -Uri $uri -Headers $headers -Body $body |
}}}\\ |
\\ |
!!! 4. Job Example:\\ |
\\ |
Sample job.XML can be downloaded here: [CrushTaskExample19/job.XML]\\ |
\\ |
[CrushTaskExample19/grant_sharepoint_site_access_job.png]\\ |
\\ |
Tasks:\\ |
[CrushTaskExample19/find_a_file.png]\\ |
\\ |
Find any local file on the server. Settings:\\ |
{{{ |
Don't Add Folders: true |
Max Items to Find: 1 |
Depth: 1 |
}}}\\ |
\\ |
[CrushTaskExample19/get_acccess_token_variables.png]\\ |
You need the following variables to obtain an access token:\\ |
{{{ |
sites_full_control_client_id = XXXX-XXX-XXX-XXX |
(See at App Registration -> Overview -> Application (client) ID) |
|
sites_full_control_client_secret_password = XXXX-XXX-XXX-XXX |
(See at App Registration -> Manage -> Certificates & secrets) |
|
tenant_id = XXXX-XXX-XXX-XXX |
(See at App Registration -> Overview -> Directory (tenant) ID) |
|
get_access_token_http_post_data = client_id={sites_full_control_client_id}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={sites_full_control_client_secret_password}&grant_type=client_credentials |
|
}}}\\ |
\\ |
[CrushTaskExample19/get_access_token_http_1.png]\\ |
\\ |
{{{ |
|
URL : https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token |
|
HTTP Method: POST |
|
POST Data: {get_access_token_http_post_data} |
|
Expected Response Codes: 200,204 |
|
}}}\\ |
\\ |
[CrushTaskExample19/get_access_token_http_2.png]\\ |
\\ |
{{{ |
|
Header: Content-Type application/x-www-form-urlencoded |
|
}}}\\ |
\\ |
}}}\\ |
\\ |
[CrushTaskExample19/parse_access_token_from_response.png]\\ |
\\ |
{{{ |
|
access_token_response = {json_parse_start}{http_response_log}{json_parse_end} |
|
sharepoint_site_relative_path = YOUR.sharepoint.com:/sites/YOUR_Site_Path/: |
|
}}} |
\\ |
[CrushTaskExample19/get_site_permission_http_1.png]\\ |
\\ |
{{{ |
|
URL: https://graph.microsoft.com/v1.0/sites/{sharepoint_site_relative_path}/permissions |
|
HTTP Method: GET |
|
Expected Response Codes: 200,204 |
|
}}} |
\\ |
[CrushTaskExample19/get_site_permission_http_2.png]\\ |
\\ |
{{{ |
|
Header: Authorization Bearer {access_token} |
|
Header: Accept application/json |
|
}}}\\ |
\\ |
[CrushTaskExample19/new_permission_related_variables.png]\\ |
\\ |
{{{ |
|
site_slected_app_id = XXXX-XXX-XXX-XXX |
(See at App Registration -> Overview -> Application (client) ID) |
|
identity_name = CrushFTP - Grant Write Access to App Registration - {site_slected_app_id} |
|
sharepoint_grant_permission_http_post_data = {n} |
"roles": [{n} |
"write"{n} |
],{n} |
"grantedToIdentities": [{n} |
{{n} |
"application": {{n} |
"id": "{site_slected_app_id}",{n} |
"displayName": "{identity_name}"{n} |
}{n} |
}{n} |
]{n} |
} |
|
}}}\\ |
\\ |
[CrushTaskExample19/new_permission_http_1.png]\\ |
\\ |
{{{ |
|
URL : https://graph.microsoft.com/v1.0/sites/{sharepoint_site_relative_path}/permissions |
|
HTTP Method: POST |
|
POST Data: {sharepoint_grant_permission_http_post_data} |
|
Expected Response Codes: 201,204 |
|
}}}\\ |
\\ |
[CrushTaskExample19/new_permission_http_2.png]\\ |
\\ |
{{{ |
|
Header: Authorization Bearer {access_token} |
|
Header: Content-Type application/json |
|
Header: Accept application/json |
|
}}}\\ |
\\ |
Reload the site permissions, including the newly created one.\\ |
\\ |
[CrushTaskExample19/get_site_permission_http_1.png]\\ |
\\ |
[CrushTaskExample19/check_new_permission.png]\\ |
\\ |
[CrushTaskExample19/error_handler_task.png]\\ |
\\ |