Проблема десериализации 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
         }
      }
   ]
}

ОБНОВИТЬ:

Я нахожусь в диалоге с одним из авторов проекта, и он любезно указал мне на это сообщение в блоге:

http://blogs.technet.com/b/ad/archive/2015/11/23/azure-ad-helping-you-adding-scim-support-to-your-applications.aspx

Он также обновил библиотеку 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);

И вуаля! Свойства моего объекта сейчас десериализуются...

Другие вопросы по тегам