编程语言
首页 > 编程语言> > c#-在.net核心Web API中自动添加策略属性

c#-在.net核心Web API中自动添加策略属性

作者:互联网

我正在使用.net Core 2.1 Web API.我正在使用基于操作的身份验证.因此,我添加了每个方法[Authorize(Policy =“ …..”)],如下所示.但是,我不想每次都写.我想从方法名称中自动获取策略名称.我该如何实现?

namespace University.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UniversityController : ControllerBase
    {
        private readonly IUniversityService universityService;

        public UniversityController(IUniversityService universityService)
        {
            this.universityService = universityService;
        }

        [Authorize(Policy = "GetUniversities")]
        [HttpGet("GetUniversities")]
        public async Task<ServiceResult> GetUniversities()
        {
            return await universityService.GetUniversities();
        }

        [Authorize(Policy = "GetStudents")]
        [HttpGet("GetStudents")]
        public async Task<ServiceResult> GetStudents()
        {
            return await universityService.GetStudents();
        }

        [Authorize(Policy = "DeleteUniversity")]
        [HttpGet("DeleteUniversity")]
        public async Task<ServiceResult> DeleteUniversity(int universityId)
        {
            return await universityService.DeleteUniversity(universityId);
        }
    }
}

解决方法:

您可以为此使用custom convention,从而可以自定义application model.使用约定,您可以使用该约定的全局注册或通过在操作上使用属性来将过滤器自动添加到项目中的每个操作等

这是您自定义约定的示例实现:

public class SomeActionModelConvention : IActionModelConvention
{
    public void Apply(ActionModel model)
    {
        model.Filters.Add(new AuthorizeFilter(model.ActionName));
    }
}

在此示例中,我们实现了IActionModelConvention,该方法定义了MVC框架在初始化时调用的Apply方法.在上面的实现中,我们只是向使用动作名称作为策略名称的模型添加AuthorizeFilter.

为了注册约定,请通过Startup.ConfigureServices中的MvcOptions将其添加.例如.:

serices.AddMvc(options => options.Conventions.Add(new SomeActionModelConvention()));

正如我上面所建议的,可以使用属性来注册该属性,但是在这种情况下这没有多大意义,因为您必须将该属性添加到动作本身中,这会破坏诸如这个约定.

但是,如果您希望将此属性作为控制器级别的属性应用,以便更具选择性,则可以改为实现类似的自定义控制器约定.这是一个示例:

public class SomeControllerModelConvention : Attribute, IControllerModelConvention
{
    public void Apply(ControllerModel model)
    {
        foreach (var actionModel in model.Actions)
            actionModel.Filters.Add(new AuthorizeFilter(actionModel.ActionName));
    }
}

除了这三个区别之外,这与SomeActionModelConvention非常相似:

>它实现了IControllerModelConvention,因此,它被每个控制器而不是每个动作调用.
> Apply被传递给ControllerModel,因此我们遍历它的所有动作并将AuthorizeFilter应用于这些动作.
>它扩展了属性,以便可以将其用作属性.

使用此方法时,无需在Startup.ConfigureServices中添加约定-而是可以将其作为属性添加.例如.:

[Route("api/[controller]")]
[ApiController]
[SomeControllerModelConvention]
public class UniversityController : ControllerBase
    ...

最后,如果您想将约定应用于控制器但使用代码来执行,则可以在Startup.ConfigureServices中注册约定(与SomeActionModelConvention方法一样),然后自定义Apply的实现,仅根据自己的逻辑添加过滤器.由于已经进行了足够长的时间,因此我将不再赘述.

标签:asp-net-core-2-1,asp-net-core-webapi,asp-net-core,c
来源: https://codeday.me/bug/20191024/1924349.html