Мы используем Graph API для создания и обновления элемента списка SharePoint. Мы назначили внешних пользователей в группу пользователей сайта. Внешние пользователи авторизуются в домене с помощью AAD и могут успешно добавлять и просматривать элементы списка. Однако, когда один и тот же внешний пользователь во время того же сеанса пытается изменить свойства элемента списка для созданного им элемента, система выдает ошибку 403 Forbidden
. Вот запрос PATCH
, который мы отправляем в SharePoint. Токен доступа тот же, который использовался для создания элемента списка. Список содержит документы в нем.
PATCH https://graph.microsoft.com/v1.0/sites/mydomain.sharepoint.com:/sites/mysite:/lists/mylist/items/1780/fields
{
"CaseNumber": "13XX17101310238",
"AppointmentID": "13App17101310238",
"DocumentURL":
"%7B0499F164-3320-4B66-A2B7-B51D1C73F502%7D&file=2018-04-26%2015.45.43.8965PM.docx"
}
Есть идеи, где мы теряем это? Я заинтригован 403
, так как документ был загружен тем же пользователем, в том же сеансе, поэтому авторизация здесь не должна была быть проблемой. Наш полный фрагмент кода выглядит следующим образом
public async Task<string> UpdateListItemsByItemID(string listItemID, string documentURL)
{
string responseString = string.Empty;
try
{
string addItemJsonString = "{\"CaseNumber\":\"13XX17101310238\",\"AppointmentID\":\"13App17101310238\",\"DocumentURL\":\"https://document\"}";
string requestUrl = "https://graph.microsoft.com/v1.0/sites/mydomain.sharepoint.com:/sites/mysite:/lists/mylist/items/1782/fields";
HttpClient client = new HttpClient();
HttpRequestMessage message = new HttpRequestMessage(new HttpMethod("PATCH"), requestUrl);
message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
message.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
message.Content = new StringContent(addItemJsonString, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.SendAsync(message);
if (response.IsSuccessStatusCode)
responseString = await response.Content.ReadAsStringAsync();
else
responseString = "Error in response";
}
catch (Exception ex)
{
responseString = "Exception: " + ex.Message;
}
return responseString;
}
Область полномочий пользователя приведена ниже. То же самое для всех внешних пользователей, где им разрешено делать все
Сообщение с запросом выглядит следующим образом
{
Method: PATCH,
RequestUri: "https://graph.microsoft.com/v1.0/sites/mydomain.sharepoint.com:/sites/mysite:/lists/mylist/items/1780/fields",
Version: 2.0,
Content: System.Net.Http.StringContent,
Headers: {
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFEWDhHQ2k2SnM2U0s4MlRzRDJQYjdybFJMbUdDcDFvb2pzdjdXSjYwX1EtNk83UkFZVTFxRXlqYTQ4TzcxbUJzSnJ2blpicGpneFdJbjQzZ2JwcmZVa081SG1CM09xUnJhc1Fzdlp3OU9HdVNBQSIsImFsZyI6IlJTMjU2IiwieDV0IjoiRlNpbXVGckZOb0Mwc0pYR212MTNuTlpjZURjIiwia2lkIjoiRlNpbXVGckZOb0Mwc0pYR212MTNuTlpjZURjIn0.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMzczZDNkODItMDdiZi00MjZiLWE4ZDItNjdhOWIzZWUwNGE1LyIsImlhdCI6MTUyNDgxMTgwNywibmJmIjoxNTI0ODExODA3LCJleHAiOjE1MjQ4MTU3MDcsImFjciI6IjEiLCJhaW8iOiJBVFFBeS84SEFBQUF6djh6U21tMC90WE1nVVR3ZFplZkZraEZjOFNlaXVpdkp6enJtampLTWNKVGpXeXdoUUVLMFhVWjJRYk1CVytsIiwiYWx0c2VjaWQiOiI1OjoxMDAzM0ZGRkE4NkNGRjg0IiwiYW1yIjpbInB3ZCJdLCJhcHBfZGlzcGxheW5hbWUiOiJQcm9saWZpYyBDYXJlIFNvbHV0aW9ucyIsImFwcGlkIjoiOGM1Yzg5ZDYtMjVmNi00Yjg2LWE2MmYtY2RiNTAxODY1NjFmIiwiYXBwaWRhY3IiOiIwIiwiZV9leHAiOjI2MjgwMCwiZW1haWwiOiJydXNzZWxsLm1hbm5pbmdAY2FyaW5naGVhcnR6LmNvbSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzA1NGU4YjQwLWYxYjUtNDY2YS1hMDg0LTdlNmIwNjg1MDExNi8iLCJpcGFkZHIiOiIzOS41OS44NC4xNzEiLCJuYW1lIjoiUnVzc2VsbCBNYW5uaW5nIiwib2lkIjoiZjkyN2I4ZWUtNTRhZi00ZGIzLWI5ZmItYTMyODIyYmVlYTEyIiwicGxhdGYiOiIzIiwicHVpZCI6IjEwMDMwMDAwQThCQkRFQTYiLCJzY3AiOiJBbGxTaXRlcy5GdWxsQ29udHJvbCBBbGxTaXRlcy5NYW5hZ2UgQWxsU2l0ZXMuUmVhZCBBbGxTaXRlcy5Xcml0ZSBCb29raW5ncy5NYW5hZ2UuQWxsIEJvb2tpbmdzLlJlYWQuQWxsIEJvb2tpbmdzLlJlYWRXcml0ZS5BbGwgQm9va2luZ3NBcHBvaW50bWVudC5SZWFkV3JpdGUuQWxsIENhbGVuZGFycy5SZWFkIENhbGVuZGFycy5SZWFkLlNoYXJlZCBDYWxlbmRhcnMuUmVhZFdyaXRlIENhbGVuZGFycy5SZWFkV3JpdGUuU2hhcmVkIENvbnRhY3RzLlJlYWQgQ29udGFjdHMuUmVhZC5TaGFyZWQgQ29udGFjdHMuUmVhZFdyaXRlIENvbnRhY3RzLlJlYWRXcml0ZS5TaGFyZWQgRGV2aWNlLkNvbW1hbmQgRGV2aWNlLlJlYWQgRGV2aWNlTWFuYWdlbWVudEFwcHMuUmVhZC5BbGwgRGV2aWNlTWFuYWdlbWVudEFwcHMuUmVhZFdyaXRlLkFsbCBEZXZpY2VNYW5hZ2VtZW50Q29uZmlndXJhdGlvbi5SZWFkLkFsbCBEZXZpY2VNYW5hZ2VtZW50Q29uZmlndXJhdGlvbi5SZWFkV3JpdGUuQWxsIERldmljZU1hbmFnZW1lbnRNYW5hZ2VkRGV2aWNlcy5Qcml2aWxlZ2VkT3BlcmF0aW9ucy5BbGwgRGV2aWNlTWFuYWdlbWVudE1hbmFnZWREZXZpY2VzLlJlYWQuQWxsIERldmljZU1hbmFnZW1lbnRNYW5hZ2VkRGV2aWNlcy5SZWFkV3JpdGUuQWxsIERldmljZU1hbmFnZW1lbnRSQkFDLlJlYWQuQWxsIERldmljZU1hbmFnZW1lbnRSQkFDLlJlYWRXcml0ZS5BbGwgRGV2aWNlTWFuYWdlbWVudFNlcnZpY2VDb25maWcuUmVhZC5BbGwgRGV2aWNlTWFuYWdlbWVudFNlcnZpY2VDb25maWcuUmVhZFdyaXRlLkFsbCBEaXJlY3RvcnkuQWNjZXNzQXNVc2VyLkFsbCBEaXJlY3RvcnkuUmVhZC5BbGwgRGlyZWN0b3J5LlJlYWRXcml0ZS5BbGwgRUFTLkFjY2Vzc0FzVXNlci5BbGwgRWR1QWRtaW5pc3RyYXRpb24uUmVhZCBFZHVBZG1pbmlzdHJhdGlvbi5SZWFkV3JpdGUgRWR1QXNzaWdubWVudHMuUmVhZCBFZHVBc3NpZ25tZW50cy5SZWFkQmFzaWMgRWR1QXNzaWdubWVudHMuUmVhZFdyaXRlIEVkdUFzc2lnbm1lbnRzLlJlYWRXcml0ZUJhc2ljIEVkdVJvc3Rlci5SZWFkIEVkdVJvc3Rlci5SZWFkQmFzaWMgRWR1Um9zdGVyLlJlYWRXcml0ZSBlbWFpbCBGaWxlcy5SZWFkIEZpbGVzLlJlYWQuQWxsIEZpbGVzLlJlYWQuU2VsZWN0ZWQgRmlsZXMuUmVhZFdyaXRlIEZpbGVzLlJlYWRXcml0ZS5BbGwgRmlsZXMuUmVhZFdyaXRlLkFwcEZvbGRlciBGaWxlcy5SZWFkV3JpdGUuU2VsZWN0ZWQgRmluYW5jaWFscy5SZWFkV3JpdGUuQWxsIEdyb3VwLlJlYWQuQWxsIEdyb3VwLlJlYWRXcml0ZS5BbGwgSWRlbnRpdHlQcm92aWRlci5SZWFkLkFsbCBJZGVudGl0eVByb3ZpZGVyLlJlYWRXcml0ZS5BbGwgSWRlbnRpdHlSaXNrRXZlbnQuUmVhZC5BbGwgTWFpbC5SZWFkIE1haWwuUmVhZC5TaGFyZWQgTWFpbC5SZWFkV3JpdGUgTWFpbC5SZWFkV3JpdGUuU2hhcmVkIE1haWwuU2VuZCBNYWlsLlNlbmQuU2hhcmVkIE1haWxib3hTZXR0aW5ncy5SZWFkIE1haWxib3hTZXR0aW5ncy5SZWFkV3JpdGUgTWVtYmVyLlJlYWQuSGlkZGVuIE15RmlsZXMuUmVhZCBNeUZpbGVzLldyaXRlIE5vdGVzLkNyZWF0ZSBOb3Rlcy5SZWFkIE5vdGVzLlJlYWQuQWxsIE5vdGVzLlJlYWRXcml0ZSBOb3Rlcy5SZWFkV3JpdGUuQWxsIE5vdGVzLlJlYWRXcml0ZS5DcmVhdGVkQnlBcHAgb2ZmbGluZV9hY2Nlc3Mgb3BlbmlkIFBlb3BsZS5SZWFkIFBlb3BsZS5SZWFkLkFsbCBwcm9maWxlIFJlcG9ydHMuUmVhZC5BbGwgU2l0ZXMuRnVsbENvbnRyb2wuQWxsIFNpdGVzLk1hbmFnZS5BbGwgU2l0ZXMuUmVhZC5BbGwgU2l0ZXMuUmVhZFdyaXRlLkFsbCBTaXRlcy5TZWFyY2guQWxsIFRhc2tzLlJlYWQgVGFza3MuUmVhZC5TaGFyZWQgVGFza3MuUmVhZFdyaXRlIFRhc2tzLlJlYWRXcml0ZS5TaGFyZWQgVGVybVN0b3JlLlJlYWQuQWxsIFRlcm1TdG9yZS5SZWFkV3JpdGUuQWxsIFVzZXIuSW52aXRlLkFsbCBVc2VyLlJlYWQgVXNlci5SZWFkLkFsbCBVc2VyLlJlYWRCYXNpYy5BbGwgVXNlci5SZWFkV3JpdGUgVXNlci5SZWFkV3JpdGUuQWxsIFVzZXJUaW1lbGluZUFjdGl2aXR5LldyaXRlLkNyZWF0ZWRCeUFwcCIsInN1YiI6IkVBaVhmeWdJMk1Xa0N5UkVMTjdYMkl0Yml3QnliVXZ1TXFNaF8xdURKWjgiLCJ0aWQiOiIzNzNkM2Q4Mi0wN2JmLTQyNmItYThkMi02N2E5YjNlZTA0YTUiLCJ1bmlxdWVfbmFtZSI6InJ1c3NlbGwubWFubmluZ0BjYXJpbmdoZWFydHouY29tIiwidXRpIjoiTGMwQVZQV01jRUNaUDJMVktyWURBQSIsInZlciI6IjEuMCJ9.xsdOu-5xoLXk5Galaoy0YQNvXzb3K_W0sL--_y7EmM-ubLE5nCWdWhf81gIqM2ONcEGSejVgmWvOlQZqiv8mccrhONHZ3lS4Jf_SsjxRWmVINQ8Q-3M_2RF60tFGQ0Cf6hWMGYGO33OfZsLIf1Dn5PSt7iWKUrNNgiJIks8imcb7KQwzy24Qsh8OTJPmN_0Wec18d0dE2tVjCOqEDACpG7yp5xmea8vM8UE0dyzCM7iRhwM2Ez6Mv-XsFnd663BlyzL6JUN8WHemjv9q_P2IcvCt9Jf2cN3g0CBtj2d7uUlgEpTZ_Tz652BMYQbbFMeigvOkIjG-VKMYldQ6FuKjvA
Content-Type: text/plain;
charset=utf-8
Content-Length: 28
}
}
Полный код ошибки:
{
StatusCode: 403,
ReasonPhrase: 'Forbidden',
Version: 1.1,
Content: System.Net.Http.StreamContent,
Headers:{
client-request-id: 1f5f91af-32d8-4a41-9375-8495a675d657
Strict-Transport-Security: max-age=31536000
request-id: 1f5f91af-32d8-4a41-9375-8495a675d657
Transfer-Encoding: chunked
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"SouthEast Asia","Slice":"SliceA","Ring":"2","ScaleUnit":"000","Host":"AGSFE_IN_1","ADSiteName":"SIN"}
}
Duration: 4018.2188
Cache-Control: private
Date: Fri, 27 Apr 2018 06:55:16 GMT
Content-Type: application/json}
}
Ответ, который мы получаем, следующий:
Response : {StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:{ client-request-id: 03cc9d52-cc1f-4889-b9b5-4ca14bdc0aec Strict-Transport-Security: max-age=31536000 request-id: 03cc9d52-cc1f-4889-b9b5-4ca14bdc0aec Transfer-Encoding: chunked x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Europe","Slice":"SliceA","Ring":"3","ScaleUnit":"001","Host":"AGSFE_IN_24","ADSiteName":"DUB"}} Duration: 413.1109 Cache-Control: private Date: Tue, 01 May 2018 13:23:39 GMT Content-Type: application/json Content-Length: 256}}
Response Content: { "error": { "code": "accessDenied, message: The caller does not have permission to perform the action.", "innerError": { "request-id": "03cc9d52-cc1f-4889-b9b5-4ca14bdc0aec", "date": "2018-05-01T13:23:39" }}}