How to grant Graph API access only to a specific sharepoint folder (to a third party)

Luciano Carvajal 0 Reputation points
2024-11-04T14:39:12.2366667+00:00

Hello everyone,

My organization needs to grant permissions to a third-party application to automatically upload files to a specific folder in SharePoint. I’ve been following the approach mentioned in this post: Restrict app access of Graph APIs to specific site.

Here’s the setup so far:

Created two App Registrations in Azure AD:

  • One with Sites.Selected (application permissions)
  • Another with Sites.FullControl.All (application permissions)
    1. Following the instructions in the post, I initially tried granting access to the site for the Sites.Selected app registration using its own credentials. However, this attempt returned an “Access denied” response.
    2. I then retried, using the Sites.FullControl.All app registration credentials to grant site access to the Sites.Selected app, and this time it worked.
  • Problem: When I proceed to grant permission to the specific folder within the site, I receive the following error response: {"error":{"code":"invalidRequest","message":"Invalid request","innerError":{"date":"(...)","request-id":"(...)","client-request-id":"(...)"}}} Im using the next python code
import requests
import json


# Step 0: Auth token

url = f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token'

body = {
    'grant_type': "client_credentials",
    'client_id': client_id,
    'client_secret': client_secret,
    'scope': "https://graph.microsoft.com/.default"
}

headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
}

response = requests.post(url, data=body, headers=headers)

# Verification
if response.status_code == 200:
    print('    Success!')
    response_data = response.json()
    access_token = response_data.get('access_token')
    print(access_token)
else:
    print(f'get_token: Error : {response.status_code}')
    print(response.text)
    access_token = ''






# Step 1: Grant access to the site (already done)

# url = f"https://graph.microsoft.com/v1.0/sites/{site_id}/permissions"

# headers = {
#     'Authorization': f'Bearer {access_token}',
#     'Content-Type': 'application/json'
# }

# body = {
#     "roles": ["read", "write"],
#     "grantedToIdentities": [
#         {
#             "application": {
#                 "id": client_id_receiver,
#                 "displayName": display_name_receiver
#             }
#         }
#     ]
# }

# response = requests.post(url, json=body, headers=headers)

# if response.status_code == 200:
#     print('Success!')
#     response_json = response.json()
#     print(json.dumps(response_json, indent=4))
# else:
#     print(f'Error : {response.status_code}')
#     print(response.text)






# Step 2: Grant access to the folder

url = f'https://graph.microsoft.com/v1.0/sites/{site_id}/drive/items/{folder_id}/permissions'

headers = {
    'Authorization': f'Bearer {access_token}',
    'Content-Type': 'application/json'
}

body = {
    "roles": ["read", "write"],
    "grantedToIdentities": [
        {
            "application": {
                "id": client_id_receiver,
                "displayName": display_name_receiver
            }
        }
    ]
}

response = requests.post(url, json=body, headers=headers)

# Verification
if response.status_code == 200:
    print('Success')
    response_json = response.json()
    print(json.dumps(response_json, indent=4))
else:
    print(f'Error: {response.status_code}')
    print(response.text)
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
12,465 questions
SharePoint Development
SharePoint Development
SharePoint: A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.Development: The process of researching, productizing, and refining new or existing technologies.
3,106 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Emily Du-MSFT 47,926 Reputation points Microsoft Vendor
    2024-11-05T03:08:29.37+00:00

    1.You need both Sites.Selected and Sites.FullControl.All to grant access for a specific site collection.

    Sites.Selected is an endpoint which allows administrator to grant Read, Write, ReadWrite, FullControl and so on permissions for an application’s access to be limited to a specific site collection.

    So, first develop application with Sites.Selected permission, then use Sites.Selected endpoint to grant FullControl permission for an application’s access to a specific site collection.

    2.After granting FullControl permission for an application’s access to a specific site collection, you could use below Graph API to grant write permission for a folder.

    (1)Get drive id.

    GET https://graph.microsoft.com/v1.0/sites/{site-id}/drives

    (2)Get folder id

    GET https://graph.microsoft.com/v1.0/sites/{site-id}/drives/{drive-id}/root/children

    (3)Grant access

    POST https://graph.microsoft.com/v1.0/sites/{site-id}/drives/{drive-id}/items/{folder-id}/invite

    Content-type: application/json

    {

    "recipients": [

    {

    "email": "user@tenant.OnMicrosoft.com"

    }

    ],

    "message": "Here's the file that we're collaborating on.",

    "requireSignIn": true,

    "sendInvitation": true,

    "roles": [ "write" ],

    "password": "password123",

    "expirationDateTime": "2024-12-05T14:00:00.000Z"

    }

    Reference:

    https://learn.microsoft.com/en-us/graph/api/driveitem-invite?view=graph-rest-1.0&tabs=http


    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.