I'm trying to get RoleDefinitionBindings using REST GET call in python
The problem is that on some calls I get a proper response, i.e,
https://my_company.sharepoint.com/_api/Web/RoleAssignments(25)/RoleDefinitionBindings
but on the other I get 'Access denied'. I.e on
https://my_company.sharepoint.com/sites/Company/_api/Web/RoleAssignments(4)/RoleDefinitionBindings
I get
AccessDeniedError("403: https://my_company.sharepoint.com/sites/Company/_api/Web/RoleAssignments(4)/RoleDefinitionBindings:
{'odata.error': {'code': '-2147024891, System.UnauthorizedAccessException',
'message': {'lang': 'en-US',
'value': 'Access denied. You do not have permission to perform this action or access this resource.'}}}")
I can't figure out what is the problem,
I'm using all possible scopes for ShapePoint for my App in Active Directory:
"https://my_company.sharepoint.com/AllSites.FullControl",
"https://my_company.sharepoint.com/AllSites.Read",
"https://my_company.sharepoint.com/User.Read.All",
"https://my_company.sharepoint.com/AllSites.Manage",
"https://my_company.sharepoint.com/AllSites.Write",
"https://my_company.sharepoint.com/MyFiles.Read",
"https://my_company.sharepoint.com/MyFiles.Write",
"https://my_company.sharepoint.com/Sites.Search.All",
"https://my_company.sharepoint.com/TermStore.Read.All",
"https://my_company.sharepoint.com/TermStore.ReadWrite.All",
"https://my_company.sharepoint.com/User.ReadWrite.All"
The problem was that I wasn't the Admin on SharePoint site (although I was the admin on Azure AD).
Once I added myself as admin to SharePoint, the issue was solved
Related
My goal is to get the list of sites with their web URL from REST API. I created one application in my tenant by granting it SharePoint API permissions.
I received the access token with client_credentials flow:
POST https://login.microsoft.com/864cc7c2-e44a-4a7e-bc1a-42b37ca38e66/oauth2/v2.0/token
client_id - 3affdc0e-04b4-495f-9346-7f5beda9c5ce,
grant_type - client_credentials,
client_secret - xxxxxx,
scope - https://< mytenant >.sharepoint.com/.default
But the issue is when I use that token to call the API. When I pass the Bearer token to call API, it's giving 401 unauthorized error like this:
{ 'error': { 'code': 'InvalidAuthenticationToken', 'message': 'Access token validation failure. Invalid Audience. ' } }
I think I messed up somewhere but don't know where in particular. Can anyone help me out?
But if I call the same in Microsoft Graph, I'm getting what I want which is very strange.
I tried to reproduce the same in my environment via Postman and got the below results:
I created an Azure AD application and granted SharePoint permissions like this:
I generated the access token with same parameters as you like below:
POST https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token
Response:
When I tried to get the list of sites with their web URLs using below query, I got the same error:
GET https://graph.microsoft.com/v1.0/sites?$select=webUrl,siteCollection
Response:
To resolve the error, you need to do changes like below:
Make sure to grant API permissions for Microsoft Graph instead of SharePoint like below:
Change the scope as https://graph.microsoft.com/.default to get access token like below:
Using the above token, I got the list of sites with their web URLs successfully like below:
Reference:
List sites - Microsoft Graph v1.0 | Microsoft Docs
You can't use the token of the SPO api to call the graph API endpoint, you should call the SPO api endpoint to list the websites:
GET https://{tenant-name}.sharepoint.com/_api/v2.0/sites
I have been following this tutorial on how to create a SharePoint webhook subscription, and after authenticating and getting the access token, actually trying to send the request to add a webhook subscription to a SharePoint list through Postman gives me an "Access is denied HRESULT: 0x80070005" error:
Error message
Going into the Postman console to see a more verbose error message shows "917656; Access+denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically."
I have tried all of the following:
Gone into SharePoint to enable Sites.Manage.All permissions for my Azure AD App
Reauthorized with several accounts with various access levels
Verified that ngrok, my webhook receiver, and Azure AD App were all running and all connection strings/client ids/secrets were valid.
Could it be that I'm missing something else in regards to SharePoint permissions for my Azure AD App, or is it another issue?
I tried to reproduce in my environment its working fine getting the access token added webhook subscription to a SharePoint list through Postman
First, Check whether you are added content-type and accept in header
This error may cause because of some security issue postman is not authenticated and not authorized to get data from the SharePoint. For this try to register an app using your URL modify at end /_layouts/15/appregnew.aspx
For sample:
https://imu.sharepoint.com/sites/mirror/_layouts/15/appregnew.aspx
Hope you have access, try to register your app as below:
Here, you need to give permission to that particular app such as Full control permission as below snip link :
In App's permission request XML apply permission as below:
And, Click Create and pop up will display trust it. click trust it site setting tab will display if you click that site collection app permission your postman right side will display client id#tenant id
To get the access token click launchpad -> create request ->https://accounts.accesscontrol.windows.net/Tenant ID()/tokens/OAuth/2/
Try to add values in Body tab like
grant_type - client_credentials
Client_id - ClientID#TenantID
Client_secret - Clientsecret
resource - resource/siteDomain#TenantID
Make sure in your Url remove parenthesis in your TenanID and site domain is in your Url like ***.sharepoint.com
Finally, i have added Authorization in header and in value Bearer access token make sure to remember space between bearer and Your access token, I am getting result successfully without any Access Denied error.
For your Reference :
OfficeDev/TrainingContent
Revisit these things
App registered in AD is having AllSites.Manage permission (delegated) and admin consent granted.
While getting access token via postman, use scope as https://yourtenant.sharepoint.com/.default
headers : Content-Type = application/json, Accept = application/json;odata=verbose
I am using the google drive python API to write fetch files, create an excel out of the file in python and then write the resulting excel file back to google drive. Important to note is that I am executing from a jupyter notebook that runs on an AWS EC2 instance. This goes well through the use of:
file = service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
However when the input is changed I need to overwrite the file with the new excel. I tried to do this in two ways. The first is to delete the file using:
service.files().delete(fileId=file_id).execute()
and then to just create the new file. Through the method below this returns the following error:
HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1hLSsfGDMpnvpYTgFpuVS7Suyctc4CQJQwGgcnFuoAnU? returned "The user does not have sufficient permissions for this file.". Details: "[{'domain': 'global', 'reason': 'insufficientFilePermissions', 'message': 'The user does not have sufficient permissions for this file.'}]">
When I try to change the persmissions using:
def set_permission(service, file_id):
print(file_id)
print(service.permissions().list(fileId=file_id).execute())
try:
permission = {'type': 'anyone',
'value': 'anyone',
'role': 'owner'}
return service.permissions().update(fileId=file_id,body=permission, permissionId="0618xxx9047xxx522413", transferOwnership=True).execute()
except errors.HttpError as error:
return print('Error while setting permission:', error)
I get:
HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1hLSsfGDMpnvpYTgFpuVS7Suyctc4CQJQwGgcnFuoAnU? returned "The user does not have sufficient permissions for this file.". Details: "[{'domain': 'global', 'reason': 'insufficientFilePermissions', 'message': 'The user does not have sufficient permissions for this file.'}]">
When I try to update the file using:
file = service.files().update(fileId=file_id, media_body=media).execute()
I get:
HttpError: <HttpError 500 when requesting https://www.googleapis.com/upload/drive/v3/files/1hLSsfGDMpvpYTgFpuVS7Suyctc4CQJQwGgcnFuoAnU?alt=json&uploadType=media returned "Internal Error". Details: "[{'domain': 'global', 'reason': 'internalError', 'message': 'Internal Error'}]">
I tried the solution metioned here: Frequent HTTP 500 Internal Errors with Google Drive drive.files.get API but to no avail as well
I am really at a loss here at what I can still try to do. Preferably I would want the .update() method to work however ommiting the http 500 error does not seem to be an option. Anyone knows how I can fix the http 500 error (or perhaps get the delete->create option to work)?
With kind regards,
Jonas
P.S. I tried to set the service url as owner in the google developer console but this did not help either.
The problem you are encountering here seems to stem from the fact that you are trying to access a file which belongs to the service account.
Since you only have the writer permission, you are not allowed to change the permissions for this file, nor delete it, hence the 403 The user does not have sufficient permissions for this file. error you are encountering.
A possible way of solving this is by executing the request which change the permissions/delete file on behalf of the service account.
How to do this?
First of all you should retrieve the credentials for the service account from the GCP project the account belongs to.
Afterwards, generate a key for this account in the JSON format and download it.
Afterwards, once you have retrieved the JSON file, use it (instead the ones you use when making the request on your behalf) in order to retrieve the credentials for the requests.
Service accounts are just special accounts used by an application, not a person and they do not belong to your Google Workspace domain, unlike user accounts. You cannot use them to log in either. However, what differentiates them from the others is that they can be used to impersonate another in the domain such that the authority is being delegated.
Reference
Service accounts;
Delegate domain-wide authority to your service account;
Drive API Resolve errors.
We created a sharepoint add-in with the follow permissions:
<AppPermissionRequests AllowAppOnlyPolicy="true"><AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="Read"/></AppPermissionRequests>
My understanding is that an app with tenant scope permissions should be able to read all the site contents. In this case the call to
/_api/web/lists('<id>')/items(<id>)/roleassignments
fails with the following error:
Client error 403
{
"odata.error":
{
"code":"-2147024891, System.UnauthorizedAccessException",
"message":
{
"lang":"en-US",
"value":"Access denied. You do not have permission to perform this action or access this resource."
}
}
}
Note that a call to /_api/web/lists('<id>')/items(<id>) for the same item works fine. The roleassignments call with tenant permissions is also working for one of the SPO instances but not for a different one.
We've struggled with this issue on and off, because the solution is not obvious, nor even sensible from a least-privilege perspective. In short:
Your application requires FullControl rights in order to access RoleAssignments.
More details
If using an application created by Azure AD, you can demonstrate this by granting and consenting to SharePoint permissions such as:
AllSites.Read (delegated)
MyFiles.Read (delegated)
Sites.Selected (application)
User.Read.All (delegated)
User.Read.All (application)
If using SharePoint-created application, use appregnew.aspx and appinv.aspx to create the app and grant it Read rights at some reasonable scope; try http://sharepoint/content/tenant.
Then get a bearer token using a client_credentials workflow (use Postman, for example).
Try a query like:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl
Make sure the Authorization header value is Bearer your-access-token
It will work.
Now try the same query, but with getting role assignments:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl&$expand=ListItemAllFields/RoleAssignments/RoleDefinitionBindings/Name
It will fail as you described, with status 403 and System.UnauthorizedAccessException.
Now grant and consent to the SharePoint application permission Sites.FullControl.All, or use appinv.aspx to add FullControl rights. Get a new bearer token. (The old one encodes the old rights granted to the app in the role field of the payload.). You'll need to wait a few minutes until the permissions apparently propagate from AD to SharePoint, if you're using an Azure AD application.
Try the last query again, and it will work.
IMHO, requiring FullControl in order to resolve something like a role assignment, which is needed to capture the permissions required to access content in a SharePoint library, is unjustified. I could understand, sort of, if tenant-scope Read permission were required. However, granting AllSites.Read or tenant-scope (http://sharepoint/content/tenant in appinv.aspx XML permissions) doesn't seem to enable roleassignment lookup.
I am trying to get and analyze data from office 365 resource room booking data, for that I am using graph API to find meeting times,
https://graph.microsoft.com/v1.0/me/findMeetingTimes ,
this query perfectly working on Microsoft graph explorer after given permissions to calendar.ReadWrite and calendar.ReadWrite.Shared, but this is not working through api call in SharePoint page and postman test with same permissions given in azure WEB API.
it is returning below error
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "90f335e7-1955-48c2-a9e9-300ea232e181",
"date": "2018-10-26T07:47:13"
}
}
}
If any suggestion appreciated.
I'm assuming you are using the MSGraphClient inside of SPFx, it is using the delegated permissions (not app permissions as per the comment in this thread). Can you confirm you are using this? https://learn.microsoft.com/en-us/sharepoint/dev/spfx/use-msgraph
This api (https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_findmeetingtimes) requires "Calendars.Read.Shared, Calendars.ReadWrite.Shared" as you stated.
You would need to add additional permissions for this api call to work. As you only get User.Read.All for SPFx with MSGraphClient. This is documented here https://learn.microsoft.com/en-us/sharepoint/dev/spfx/use-aadhttpclient
From your provided request Id, I can see that your request had these scopes, which is missing the Calendars.Read.Shared permissions scope.
"Mail.ReadWrite","User.ReadWrite.All","Calendars.Read","People.Read.All","Group.Read.All","Directory.ReadWrite.All","MailboxSettings.Read","Contacts.ReadWrite","Group.ReadWrite.All","Sites.Manage.All","User.Invite.All","Files.ReadWrite.All","Directory.Read.All","User.Read.All","Files.Read.All","Mail.Read","Calendars.ReadWrite","Mail.Send","MailboxSettings.ReadWrite","Contacts.Read","Sites.FullControl.All","Reports.Read.All"
Look into the permissions of findMeetingTimes. You mode of authentication could be the root cause. For me I was tryint to use Application mode and this is not supported in this API.
I used and alternative api, /calendar/getSchedule to achieve this. If you login as your userid use ME option or use application mode login to login and use {id|userPrincipalName} to get calendar details for any meeting room.
Refer: https://learn.microsoft.com/en-us/graph/api/calendar-getschedule?view=graph-rest-1.0&tabs=http
Graph API Explorer link below provides the basics on how to login and got good examples for Graph to begin with.
https://developer.microsoft.com/en-us/graph/graph-explorer