首页 > 解决方案 > 为 ASP.NET Core 控制器动态添加授权

问题描述

我有一个控制器,其中包含一些我在许多内部项目中使用的实用方法。到目前为止,我总是在每个项目中复制源文件。现在我想为这个控制器创建一个 NuGet 包,以便在内部存储库中使用。

问题在于该控制器的授权。我不想[Authorize()]在控制器类(或其操作)上放置特定属性,因为授权应该由使用包的开发人员选择:在某些项目中,每个人都可以使用控制器,在某些项目中可以使用只有经过身份验证的用户才能使用,在其他用户中可以与自定义策略一起使用。

关于如何实现目标的任何想法?

标签: asp.net-coreauthorizationnuget-package

解决方案


我会添加Authorize带有强制策略的属性,您的所有用户都必须实施该属性。像这样的东西:

[Authorise(Policy = "MyLibPolicy")]
public class LibController : Controller
{
}

然后,根据他们的需要,他们可以在他们的Configure方法中以不同的方式声明它:

如果他们需要经过身份验证的用户

services.AddAuthorization(options =>
{
    options.AddPolicy("MyLibPolicy", policy =>
    {
        policy.RequireAuthenticatedUser();
    });
});

如果他们需要自定义策略

services.AddAuthorization(options =>
{
    options.AddPolicy("MyLibPolicy", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireRole("SomeRole");
        // other requirements
    });
});

如果他们想要匿名访问

现在,这是棘手的部分,因为您不能创建空策略(策略至少需要一个要求)。

但是,您可以创建自己的自定义需求(在 Nuget 包中)以允许匿名用户(基本上,始终成功的需求)。

public class AllowAnonymousAuthorizationRequirement : AuthorizationHandler<IAuthorizationRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IAuthorizationRequirement requirement)
    {
        context.Succeed(requirement);
        return Task.CompletedTask;
    }
}

然后,您的用户需要在使用它之前进行注册,如下所示:

services.AddScoped<IAuthorizationHandler, AllowAnonymousAuthorizationRequirement>();
services.AddAuthorization(options =>
{
    options.AddPolicy("MyLibPolicy", policy =>
    {
        policy.AddRequirements(new AllowAnonymousAuthorizationRequirement());
    });
});

推荐阅读