Can I allow for unauthorized user to have access to controller if the field "allowed" in appsettings.json is true?

596 views Asked by At

As the title says, I try to let the controller distinguish between two states.

  1. If a field "allowed" in appsettings is true, allow for unauthorized users to have access to the controller.
  2. If "allowed" is false, allow access just for authorized users.

But I'm not quiet understand how can I implement it using policies. Can I pass Boolean to an authorize attribute somehow?

Edit

Controller

[Authorize(Policy ="Unauthenticated")] // to pass here some additional argument 
public string GetController();

1

There are 1 answers

0
Zhi Lv On BEST ANSWER

In the Policy based Authorization Handler method, you could get the allowed value using the Configuration provider, then, according to the value to do the policy authorization or ignore the authorization.

For example, based on this article, I have created a MinimumAgeHandler:

public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
    private readonly UserManager<ApplicationUser> _userManager; //used to get the current user information.

    private readonly IConfiguration _configuration;
    public MinimumAgeHandler(UserManager<ApplicationUser> manager, IConfiguration configuration)
    {
        _userManager = manager;
        _configuration = configuration;
    }
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MinimumAgeRequirement requirement)
    {

        if (context.User == null)
        {
            return Task.CompletedTask;
        }
        if (!context.User.HasClaim(c => c.Type == ClaimTypes.Name))
        {
            //TODO: Use the following if targeting a version of
            //.NET Framework older than 4.6:
            //      return Task.FromResult(0);
            return Task.CompletedTask;
        }

        //get the Allowed value from the appsettings.json.
        var isAllowed = _configuration["Allowed"];

        //
        if (isAllowed != "True")
        {
            //policy authorization handler
            var user = context.User;
            var age = _userManager.GetUserAsync(user).Result.Age;

            if (age >= requirement.MinimumAge)
            {
                context.Succeed(requirement);
            }
        }
        else
        {
            //ignore the policy authorization handler.
            context.Succeed(requirement);
        }
        //TODO: Use the following if targeting a version of
        //.NET Framework older than 4.6:
        //      return Task.FromResult(0);
        return Task.CompletedTask;
    }
} 

and the MinimumAgeRequirement:

public class MinimumAgeRequirement : IAuthorizationRequirement
{
    public int MinimumAge { get; }

    public MinimumAgeRequirement(int minimumAge)
    {
        MinimumAge = minimumAge;
    }
}

Then, register the Authorization:

        services.AddAuthorization(options =>
        {
            options.AddPolicy("AtLeast21", policy =>
                policy.Requirements.Add(new MinimumAgeRequirement(21)));
        });

        services.AddScoped<IAuthorizationHandler, MinimumAgeHandler>();

Add "Allowed": true, in the appsettings.json file.

Finally, add Authorize attribute in the action method:

    [Authorize(Policy = "AtLeast21")]
    public IActionResult Index()
    {
    }

By using above sample code, after user login, if the Allowed is True, it will ignore the MinimumAge validation.