通过名称和键请求参数授权对CommandHandler的请求

时间:2019-02-14 15:53:42

标签: c# .net authorization decorator cqrs

最近的项目已开始变得更加复杂,并且控制器变得过于“业务逻辑”沉重。我正在研究将我们迁移到CQRS并使用Mediatr的可行性。

当前存在的公开API方法旨在为提供的邮政编码提供完整的地址记录。

此方法接受名称,键和模型,当前使用该名称和键来选择用户,然后授权允许该用户调用此端点。如果是,则查找完成并返回地址。

我已经创建了一个Query和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
        };
    }
}

0 个答案:

没有答案