Я работаю над реализацией авторизации на моем конвейере Mediatr и столкнулся с небольшим количеством проблем.Я уже реализовал пользовательский интерфейс, который IRequest
объекты могут реализовать, чтобы сообщить поведению конвейера, что данный объект нуждается в авторизации против аутентифицированного пользователя и ClientId
, которые они передают со своим запросом.Этот слой авторизации работает отлично.Однако я хочу немного расширить это поведение и реализовать IReqestPreProcessor
, который может изменять основную команду.
В большинстве моих случаев использования аутентифицированный пользователь будет иметь претензии только к 1 клиенту.Я пытаюсь изменить конвейер для автоматического выбора идентификатора клиента пользователя из системы.Мне удалось установить логику для получения информации о клиенте пользователя, но я не могу повлиять на фактический запрос до конца его прохождения через конвейер.Теперь я не совсем уверен, как я мог бы реализовать это поведение.
Вот мой соответствующий интерфейс:
public interface IClientAuthorizationCommand
{
Guid? ClientId { get; set; }
}
И мой препроцессор запросов выглядит примерно так:
public class UserClientPreprocessor<TRequest> : IRequestPreProcessor<TRequest>
{
private readonly DbContext _context;
private readonly ICurrentUserAccessor _currentUserAccessor;
public UserClientPreprocessor(DispenseMeDbContext context, ICurrentUserAccessor currentUserAccessor)
{
_context = context;
_currentUserAccessor = currentUserAccessor;
}
public async Task Process(TRequest request, CancellationToken cancellationToken)
{
if (request is IClientAuthorizationCommand req)
{
if (req.ClientId.HasValue) return;
var user = await new UserFetcher(_context).FetchByUsername(_currentUserAccessor.GetCurrentUsername());
var clientUsers = _context.ClientUsers.Where(n =>
!n.DeletedDate.HasValue && n.UserId == user.UserId);
if (!await clientUsers.AnyAsync(cancellationToken))
throw new NoUserClientsExceptions(user.Username);
if (await clientUsers.CountAsync(cancellationToken) > 1)
throw new MultipleUserClientsException(user.Username);
((IClientAuthorizationCommand)request).ClientId = clientUsers.First()?.Client?.ClientIdentifier;
}
}
}
Если я пройдусь по приведенному выше коду, все в этом классе вызывается и работает как положено.Однако команда, которая передается другим IPipelineBehaviors, не затрагивается.