Недавний проект начал усложняться, а контроллеры становятся слишком «тяжелыми».Я изучаю возможность перехода на CQRS и использования Mediatr.
Открытый метод API, который существует в настоящее время, предназначен для предоставления полной записи адреса для предоставленного почтового индекса.
Этот метод принимает имя, ключ и модель и в настоящее время использует имя и ключ для выбора пользователя, а затем разрешает пользователю разрешать вызов этой конечной точки.Если это так, тогда поиск завершен, и адрес возвращается.
Я создал QueryHandler, который с помощью почтового индекса выполнит физический поиск и вернет полный адрес.Однако я изо всех сил пытаюсь найти разумный способ интегрировать авторизацию в этот поток.
Выполнение QueryHandler авторизации кажется неправильным, поскольку я не ожидал, что в случае сбоя ему придется выдавать ошибки, а также потому, что существует множество запросов и команд, которые необходимо авторизовать из пары ключей имени иЯ хотел бы, чтобы он был полуцентрализованным.
Я наткнулся на этот существующий ответ: https://stackoverflow.com/a/19901561/1645826, который предлагает обернуть запросы и команды в декоратор авторизации.Однако, похоже, что это основано на идее, что ей может быть предоставлен внедренный сервис, способный сообщить декоратору авторизации, каковы детали пользователя.Я не вижу разумного способа предоставления этого имени и пары ключей декоратору, поскольку они являются всего лишь двумя параметрами в моем методе.
У меня вопрос, как я могу иметь централизованный декоратор авторизации, когда информациято, что понадобится декоратору авторизации, не легко доступно и не нужно для запроса, который оформляется?
Мой метод:
[Route(Routes.GetAddress)]
public async Task<ActionResult> GetAddress(string Name, string Key, GetAddressRequest model)
{
if (Name == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "No Name Provided"); }
if (Key == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "No Key Provided"); }
if (model == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "No request Provided"); }
var user = await userManager.GetUserForAddressLookupAsync(Name, Key, Response.ClientDisconnectedToken);
if (user == null || user.AddressLookup == false) { return new HttpStatusCodeResult(HttpStatusCode.Unauthorized, "Access Denied"); }
return Json(mediator.Send(new GetAddressByPostcodeQuery { Postcode = model.Postcode }));
}
И мой QueryHandler выглядит так:
public class GetAddressByPostcodeQueryHandler : IRequestHandler<GetAddressByPostcodeQuery, GetAddressResponse>
{
public async Task<GetAddressResponse> Handle(GetAddressByPostcodeQuery request, CancellationToken cancellationToken)
{
var address = \\ stuff to get address here
return new GetAddressResponse
{
Postcode = address.Postcode,
Street = address.Street,
DependentStreet = address.DependentStreet,
Town = address.Town,
DependentLocality = address.DependentLocality,
County = address.County,
FullAddress = address.FullAddress
};
}
}