Mediatr 3.0使用管道行为进行身份验证

Bet*_*tty 10 c# mediatr

查看使用新的Mediatr 3.0功能管道行为进行身份验证/授权.

您通常会根据消息或处理程序进行身份验证吗?我问的原因是我在处理程序上进行身份验证(与MVC中的控制器相同)但是行为似乎没有关于处理程序的知识,因此我不确定这是否可行/适合.

我可以为每条消息添加一个IAuthorisationRequired标记接口,但如果消息是通知/事件并且有多个处理程序,那么可能有些应该运行而不是其他运行.真的感觉更好地检查执行实际工作的处理程序代码的auth.

希望能够在处理程序上放置[Authorize]属性并使用一个行为来检查它(我目前正是这样做但是使用基类而不是行为).

public class AuthenticationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    public Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
    {
        //Can't access handler class here, so how do I know the action requires authentication/authorization?
        return next();
    }
}

[Authorize]
public class ChangePasswordRequestHandler : IAsyncRequestHandler<ChangePassword, ReponseType>
{   
    protected override async Task<ReponseType> Handle(AsyncRequestBase<ChangePassword> message)
    {
        //change users password here
    }
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*iey 6

你是对的,RequestDelegateHandler<TResponse>不会暴露接下来会运行的处理程序,这是故意的.如果你考虑一下,MediatR 2.x中的管道使用装饰器,而装饰者可以访问decoratee的实例,我建议不要基于它进行auth.原因是如果你需要你的授权装饰器来装饰处理程序的一个特定实例 - 用特定属性装饰的那个 - 那么它们是耦合的,这会破坏装饰器的目的,你应该能够将它们放在每个其他独立的.

这就是为什么我建议基于消息的授权,至少在大多数情况下.您可以使用可扩展的设计将每条消息与多个授权规则相关联,并且行为将评估所有这些规则.

public interface IAuthorizationRule<TRequest>
{
    Task Evaluate(TRequest message);
}

public class AuthorizationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    private readonly IAuthorizationRule<TRequest>[] _rules;

    public AuthorizationBehavior(IAuthorizationRule<TRequest>[] rules)
    {
        _rules = rules;
    }

    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
    {
        // catch it or let it bubble up depending on your strategy
        await Task.WaitAll(_rules.Select(x => x.Evaluate(request)));

        return next();
    }
}
Run Code Online (Sandbox Code Playgroud)

对于特定情况,您提到,对于通知,某些处理程序可能会运行而其他处理程序不应运行,您始终可以使用针对该特定消息的授权行为,并将其有选择地应用于需要它们的处理程序.我想我的观点是,当你遇到这些特定场景时,你必须做一些自己的工作.

  • `IAuthorizationRule&lt;TRequest&gt;[] rules` 究竟是如何注入到这个管道行为中的? (2认同)