Azure AD Graph: безопасная двоичная сериализация не поддерживается на этой платформе - PullRequest
0 голосов
/ 08 ноября 2018

Мы работаем на .NET Core 2.1 и иногда получают исключение "Безопасная двоичная сериализация на этой платформе не поддерживается" при выполнении следующего запроса:

await _adClient.Users[userId].AppRoleAssignments.ExecuteAsync();

Повторное выполнение запроса часто работает, поэтому выполняется некоторое условие, при котором двоичная сериализация не предпринимается (или успешно выполняется?) Для последующих запросов? Тем не менее, если я перезапущу сервис, он часто будет работать и по первому запросу.

Мы используем более старый клиент AD Graph, потому что 1) клиент Microsoft Graph еще не полностью поддерживает AppRoleAssignments и 2) то, что поддерживается, является частью бета-версии и не рекомендуется для производственного использования.

Полный стек вызовов ниже:

System.Data.Services.Client.BaseAsyncResult.EndExecute<T>(object source, string method, IAsyncResult asyncResult)
System.Data.Services.Client.QueryResult.EndExecuteQuery<TElement>(object source, string method, IAsyncResult asyncResult)
System.Data.Services.Client.DataServiceRequest.EndExecute<TElement>(object source, DataServiceContext context, string method, IAsyncResult asyncResult)
System.Data.Services.Client.DataServiceQuery<TElement>.EndExecute(IAsyncResult asyncResult)
Microsoft.Azure.ActiveDirectory.GraphClient.Extensions.DataServiceContextWrapper+<>c__DisplayClass4c<TSource, TInterface>.<ExecuteAsync>b__4a(IAsyncResult r)
System.Threading.Tasks.TaskFactory<TResult>.FromAsyncCoreLogic(IAsyncResult iar, Func<IAsyncResult, TResult> endFunction, Action<IAsyncResult> endAction, Task<TResult> promise, bool requiresSynchronization)
Microsoft.Azure.ActiveDirectory.GraphClient.Extensions.DataServiceContextWrapper.ExecuteAsync<TSource, TInterface>(DataServiceQuery<TSource> inner)
Microsoft.Azure.ActiveDirectory.GraphClient.AppRoleAssignmentCollection.<ExecuteAsync>b__2()
Merck.SeaMonkey.Api.AzureADApi.Controllers.UserController.GetApplicationRoleAssignments(string userId) in UserController.cs

Новый клиент Microsoft Graph здесь не вариант, хотя я полагаю, что мы можем перейти к базовому интерфейсу REST, который представляет собой небольшую работу со всей логикой повторных попыток, анализом результатов и т. Д., На которые мы полагались графический клиент, чтобы сделать.

UPDATE: Укажите источник исключения, мы предполагаем, что существует проблема в сериализации объекта в ответе OData. Однако, используя AD Graph Explorer, мы видим очень простой ответ пустого массива значений вместе со ссылкой на документ метаданных для сущности. Мы часто повторяли проблему, удаляя и добавляя новые назначения ролей приложения, но мы не можем заставить ее возникать на 100% надежно. Похоже, что какое-то состояние повреждено, возможно, в каком-то внутреннем кеше?

1 Ответ

0 голосов
/ 15 ноября 2018

Я часто использую этот вызов API, но я использую прямой вызов httpClient по отношению к старому графику.

Я публикую это только в качестве ссылки - обратите внимание на явную версию в URL (1.6). Я также публикую объект, в который я десериализуюсь, это может не соответствовать официальной схеме объекта.

    // OLD Graph End point    //  like ... https://graph.windows.net/{tenant-id}/users/{id}/appRoleAssignments?api-version=1.6
   urlUserInviteToUse = "https://graph.windows.net/" + m_CfgHlp.TenIdInB2C + "/" + ObjFamilyName + "/" + DirObjIdToGet + "/" + ObjFunctionCall + "?api-version=1.6";

Из-за полезной нагрузки оставшейся строки API я эффективно использую JsonConvert.DeserializeObject для перехода от полезной нагрузки к классу объектов. Обратите внимание, что Даты не десериализованы как даты.

public class AppRoleAssignmentsRoot
{
    public string odatametadata { get; set; }
    public AppRoleAssignment[] value { get; set; }
}

public class AppRoleAssignment
{
    public string odatatype { get; set; }
    public string objectType { get; set; }
    public string objectId { get; set; }
    public object deletionTimestamp { get; set; }
    public object creationTimestamp { get; set; }
    public string id { get; set; }
    public string principalDisplayName { get; set; }
    public string principalId { get; set; }
    public string principalType { get; set; }
    public string resourceDisplayName { get; set; }
    public string resourceId { get; set; }
}
...