在运行时设置的授权变量(ASP.NET 核心)

Authorization variables set during runtime (ASP.NET Core)

我一直在寻找这个问题的答案有一段时间了,我似乎找到的是 6 多年前的答案,所以我想我会再次问这个问题来帮助我和所有人以后会找的。

我在 ASP.NET 核心框架上有一个用 C# 运行 编写的 API。在其中我有几个使用不同角色授权的控制器(有些是针对管理员的,有些是针对用户的等)。

这是一个例子:

 [ApiController]
 [Authorize(Roles = "prod-DbAdmin")]
 [Route("/products")]
 public class ProductController : ControllerBase
 {
      // some code .....
 }

现在我的问题是“角色”来自第三方生成的令牌,API 是在 3 种不同环境(开发、测试、生产)中的 kubernetes 上设置的。现在管理员不会在所有 3 个环境中默认成为管理员,令牌可能包含“Dev-DbAdmin”但不包含“Prod-DbAdmin”。

因此我无法拥有通用的 [Authorize(Roles = "DbAdmin")] 属性。我想做的是将环境相关变量发送到授权过滤器。

我有 3 个不同的 appsecrets.json 文件,每个环境一个,它们是根据我们所在的环境和每个环境中的正确角色加载的。

现在我尝试将配置文件注入控制器并在身份验证中使用正确的角色,但它拒绝说

An attribute argument must be a constant expression

所以我的问题显然是这样的,我如何将变量发送到 auth 过滤器而不是使用这些编译时常量?

根据你的描述,我建议你可以尝试使用添加策略来实现你的要求。

您可以在 startup.cs AddAuthorization 方法中根据您的环境设置策略,然后直接在控制器中使用该策略。

更多详情,您可以参考以下代码:

Startup.cs:

    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
        Configuration = configuration;
        CurrentEnvironment = env;
    }

    private IWebHostEnvironment CurrentEnvironment { get; set; }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthorization
           (
               options =>
               {
                   options.AddPolicy
                   (
                       "RolebasedonEnv",
                       policy => {
                           if (CurrentEnvironment.IsDevelopment())
                           {
                               policy.RequireRole("aadmin");
                           }
                           else
                           {
                               policy.RequireRole("else");

                           }
                       }
                   );
               }
           );
          ....

        }

控制器:

[Authorize(Policy = "RolebasedonEnv")]