Проблема десериализации SCIM в.NET
Как новичок в стандарте SCIM (Система для управления междоменной идентификацией), прошу прощения за любое невежество, поскольку я нахожусь на кривой обучения, пытаясь выяснить, как делать чистые / простые запросы для предоставления пользователям, удаления пользователей и изменения пользователей.
Я пытаюсь использовать C#/.NET, чтобы сделать HTTP-запросы REST для пользователя через SCIM, используя System.Net.Http.HttpClient
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx
Я могу сделать это успешно и получить ответ JSON от сервера, однако для того, чтобы легко прочитать объект ответа и манипулировать им, я хочу десериализовать его. После долгих чтений, пытаясь использовать такие вещи, как JsonConvert
, dynamic
и т.д. Я наткнулся на библиотеку Microsoft Nuget, которая, казалось, намекала на полезность. К сожалению, нет никаких документов для этого *
ОБНОВЛЕНО: Один из авторов обновил страницу nuget, добавив ссылку на пост в блоге, который объясняет использование.
Microsoft.SystemForCrossDomainIdentityManagement
https://www.nuget.org/packages/Microsoft.SystemForCrossDomainIdentityManagement/
Поставщик SCIM, от которого я пытаюсь получить данные, - это Facebook, используя пример, который они публикуют на своем сайте, для получения пользователя по электронной почте:
https://developers.facebook.com/docs/facebook-at-work/provisioning/scim-api
Вот пример кода в C#, который пытается получить пользователя от службы SCIM и десериализовать его. Я считаю, что queryResponse
Я вернусь, десериализован правильно, так как свойства заполнены, однако Core1EnterpriseUser
который является первым и единственным из объектов ресурсов, имеет свойства null / default.
var userName = "foo.bar@foobar.com";
var response = await client.GetAsync($"Users?filter=userName%20eq%20%22{userName}%22");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var jsonResponseProperties = await Task.Factory.StartNew(() => { return JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
var userFactory = new QueryResponseJsonDeserializingFactory<Core1EnterpriseUser>();
var queryResponse = userFactory.Create(jsonResponseProperties);
if (queryResponse.TotalResults == 1)
{
var user = queryResponse.Resources.First();
var id = user.Identifier; // this and other properties are null/false etc.
}
}
Вот пример JSON, который возвращается сервисом, когда я запрашиваю его:
{
"schemas": [
"urn:scim:schemas:core:1.0"
],
"totalResults": 1,
"itemsPerPage": 10,
"startIndex": 1,
"Resources": [
{
"schemas": [
"urn:scim:schemas:core:1.0",
"urn:scim:schemas:extension:enterprise:1.0",
"urn:scim:schemas:extension:facebook:starttermdates:1.0",
"urn:scim:schemas:extension:facebook:suppressclaimemail:1.0"
],
"id": 180383108978226,
"userName": "foo.bar\u0040foobar.com",
"name": {
"formatted": "Foo Bar",
"familyName": "Bar",
"givenName": "Foo"
},
"title": "Vice President",
"active": true,
"emails": [
{
"primary": false,
"type": "work",
"value": "foo.bar\u0040foobar.com"
}
],
"urn:scim:schemas:extension:enterprise:1.0": {
"department": "IT"
},
"urn:scim:schemas:extension:facebook:starttermdates:1.0": {
"startDate": 0,
"termDate": 0
}
}
]
}
ОБНОВИТЬ:
Я нахожусь в диалоге с одним из авторов проекта, и он любезно указал мне на это сообщение в блоге:
Он также обновил библиотеку nuget, которая теперь включает поддержку v1 SCIM, также указав, что, как свидетельствуют данные JSON, версия, используемая Facebook, v1: "urn:scim:schemas:core:1.0"
так что теперь я могу использовать Core1
вместо того, чтобы пытаться использовать Core2
классы (я обновил вопрос выше, чтобы использовать Core1EnterpriseUser
).
В настоящее время я все еще не могу правильно десериализовать свой ответ и обновлю вопрос, добавив больше информации, как она у меня есть.
Опять же, мне не нужно использовать эту библиотеку, если становится очевидно, что она не будет легко работать, поскольку я знаю, что краткое описание nuget предполагает, что она была создана для Azure AD.
Однако я был бы признателен за любые советы о том, как можно / нужно делать подобные вещи, так как я уверен, что с помощью SCIM должно быть много людей - как вы анализируете свои ответы / генерируете свои запросы так, чтобы у вас были реальные объекты? Можете ли вы автоматически проанализировать ответы для схем, чтобы дополнить объект правильными свойствами?
Вчера вечером я проснулся, создавая несколько классов моделей для работы с объектами ответа, что, похоже, работает. Если я не могу заставить работать библиотеку nuget (предпочтительный вариант), то мне придется пойти со своей собственной.:/
Спасибо еще раз петески
1 ответ
Хотя я до сих пор не знаю, как лучше всего использовать SCIM, мне удалось заставить код работать сейчас - благодаря огромному количеству благодарностей одному из авторов библиотеки nuget Крейгу МакМертри из Microsoft!
По ходу дела нужно было кое-что сгладить, например, обновить пакет nuget, включив в него предыдущую поддержку более старых объектов SCIM v1. Но вот фрагмент того, что сработало, основываясь на примере из моего вопроса, но оказалось, что он использует сериализатор Newtonsoft.:(
В коде над строкой:
var jsonResponseProperties = await Task.Factory.StartNew(() => { return JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
Был заменен на:
var jsonResponseProperties = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
И вуаля! Свойства моего объекта сейчас десериализуются...