Контекстная сериализация от конечной точки WebApi на основе разрешений

Я использую Asp.Net Web Api. Я хотел бы иметь возможность отфильтровать определенные поля в объектах ответа на основе прав доступа подключенных клиентов.

Пример:

class Foo
{
    [AccessFilter("Uberlord")]
    string Wibble { get; set; }

    string Wobble { get; set; }
}

При возврате данных в поле Wibble должен возвращаться только в том случае, если текущий контекст пользователя может удовлетворять значению "Uberlord".

Есть три пути, которые я изучаю, но у меня нет рабочего решения:

  1. Пользовательский WebApi MediaTypeFormatter.
  2. Пользовательский json.net IContractResolver.
  3. Какая-то оболочка AOP для контроллеров, которая манипулирует объектом ответа

Моя проблема с этим:

  • Пользовательский форматировщик не кажется подходящим местом для этого, но может быть единственным вариантом.
  • Пользовательский сериализатор json не будет иметь доступа к текущему контексту, поэтому мне придется разобраться с этим.
  • При использовании первых двух опций вам потребуются конкретные реализации для каждого формата ответа: json, xml, некоторый пользовательский формат и т. Д. Это будет означать, что если поддерживается другой тип ответа, то для предотвращения утечки конфиденциальных данных требуется специальный форматтер / сериализатор.
  • Оболочка контроллера AOP потребует много размышлений.

Дополнительным бонусом будет удаление значений из полей объекта входящего запроса с использованием того же механизма.

Я пропустил очевидный крюк? Это было решено другим способом?

2 ответа

Решение

На самом деле все было намного проще, чем я думал. Что я не понял, так это то, что DelegatingHandler может использоваться для управления ответом, а также запросом в конвейере Web Api.

Жизненный цикл сообщения ASP.NET Web API

Делегирующий обработчик

Делегирующие обработчики - это точка расширения в конвейере сообщений, позволяющая вам массировать запрос, прежде чем передать его остальной части конвейера. Ответное сообщение на обратном пути также должно проходить через делегирующий обработчик, поэтому любой ответ также можно отслеживать / фильтровать / обновлять в этой точке расширяемости.

Делегирующие обработчики, если требуется, также могут обойти остальную часть конвейера и отправлять обратно и Http-ответ сами.

пример

Вот пример реализации DelegatingHandler, который может либо манипулировать объектом ответа, либо полностью заменить его.

public class ResponseDataFilterHandler : DelegatingHandler
{
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken)
            .ContinueWith(task =>
            {
                var response = task.Result;

                //Manipulate content here
                var content = response.Content as ObjectContent;
                if (content != null && content.Value != null)
                {
                    ((SomeObject)content.Value).SomeProperty = null;
                }

                //Or replace the content
                response.Content = new ObjectContent(typeof(object), new object(), new JsonMediaTypeFormatter());

                return response;
            });
    }
}

У меня есть похожий вопрос в работах здесь: ASP.NET WebAPI Условная сериализация на основе роли пользователя

Предлагаемое решение, которое я придумала, состоит в том, чтобы мой ApiController наследовал от BaseApiController, который переопределяет функцию Initalize, чтобы установить соответствующий форматер в зависимости от роли пользователя. Я еще не решил, пойду ли я этим путем, но, возможно, это сработает для вас.

protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
    base.Initialize(controllerContext);
    // If the user is in a sensitive-data access role
    controllerContext.Configuration.Formatters.Add(/*My Formatter*/);
    // Otherwise use the default ones added in global app_start that defaults to remove sensitive data
}
Другие вопросы по тегам