Search code examples
asp.netasp.net-coreauthorizationasp.net-authorization

Authorization variables set during runtime (ASP.NET Core)


I have been looking for the answer to this question for some time now and all I seem to find is answers from 6+ years ago, so I figured I'd ask this question again to help me and all the people that will look for it in the future.

I have a API written in C# running on the ASP.NET Core framework. In it I have several controllers that use authorization with different roles (some are for admins some are for users etc).

Here is an example:

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

Now my issue is that the "Roles" come from a third party generated token and the API is setup on kubernetes in 3 different environments (Dev, Test, Prod). Now a admin will not by default be a admin in all 3 environments a token may contain a "Dev-DbAdmin" but not a "Prod-DbAdmin".

Hence I can't have an universal [Authorize(Roles = "DbAdmin")] attribute. What I want to do instead is to send in an environment dependent variable to the authorization filter.

I have 3 different appsecrets.json files, one for each of the environments and they are loaded based on which env we are in and the correct roles are in each of those.

Now I tried injecting the config file into the controller and using the correct role in the auth but it refused saying

An attribute argument must be a constant expression

So my question is obviously this, how do I send in variables to the auth filter instead of using these compile-time constants?


Solution

  • According to your description, I suggest you could try to use add policy to achieve your requirement.

    You could set the policy based on your environment inside the startup.cs AddAuthorization method and then directly use that policy inside the controller.

    More details, you could refer to below codes:

    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");
    
                               }
                           }
                       );
                   }
               );
              ....
    
            }
    

    Controller:

    [Authorize(Policy = "RolebasedonEnv")]