locked
Is it possible to send an extra parameter to the HandleRequirementAsync method of AuthorizationHandler? RRS feed

  • Question

  • User-1095454647 posted

    I want to be able to send a parameter to the handler, for example: ActivityId="1001", I could write some logic based on it. Can this be done? If yes how? If not then how could I access role passed in [Authorize(Policy = "Over18" ,Role ="1001")]?

    Controller:

        [Route("/test")]
        [HttpGet]
        [Authorize(Policy = "Over18" ,ActivityId ="1001")]
        public string test()
        {
            return "blah";
        }
    

    Authorization Class:

    public class Over18requirement : AuthorizationHandler<Over18requirement>, IAuthorizationRequirement
    {
        public string Activity { get; set; }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, Over18requirement requirement)
        {
    
            if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
            {
                context.Fail();
            }
    
            var dateofbirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value);
            int age = DateTime.Today.Year - dateofbirth.Year;
            if (dateofbirth > DateTime.Today.AddYears(-age))
            {
                age--;
            }
    
            if (age >= 18)
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
            return Task.CompletedTask;
        }
    }
    Monday, May 31, 2021 6:02 PM

All replies

  • User1686398519 posted

    Hi Arby360, 

    Arby360

    I could write some logic based on it. Can this be done?

    You can customize authorization attributes and authorization policy providers to meet your needs.

    1. I wrote an example based on your description, you can refer to it.
    2. Below are some links, you can refer to them, to help you understand the examples I provide.
      1. Custom Authorization attributes
      2. Policy-based authorization in ASP.NET Core
      3. Custom Authorization Policy Providers using IAuthorizationPolicyProvider in ASP.NET Core

    Startup

            public void ConfigureServices(IServiceCollection services)
            {
    ... ... services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.Name = "test"; options.LoginPath = "/Home/Test"; }); services.AddSingleton<IAuthorizationPolicyProvider,Over18PolicyProvider>(); services.AddSingleton<IAuthorizationHandler, Over18Handler>(); }

    CustomAuthorizeAttribute

        public class CustomAuthorizeAttribute : AuthorizeAttribute
        {
            public string ActivityId
            {
                get
                {
                    if (!String.IsNullOrEmpty(Policy.Substring(Policy.Length)))
                    {
                        return Policy.Substring(Policy.Length);
                    }
                    return default(string);
                }
                set
                {
                    Policy = $"{Policy}{value.ToString()}";
                }
            }
        }

    Over18PolicyProvider

        internal class Over18PolicyProvider : IAuthorizationPolicyProvider
        {
            const string POLICY_PREFIX = "Over18";
            public Task<AuthorizationPolicy> GetDefaultPolicyAsync() =>
                Task.FromResult(new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build());
            public Task<AuthorizationPolicy> GetFallbackPolicyAsync() =>
                Task.FromResult<AuthorizationPolicy>(null);
            public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
            {
               
                if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
                {
                    var ActivityId= policyName.Substring(POLICY_PREFIX.Length);
                    var policy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme);
                    policy.AddRequirements(new Over18Requirement(ActivityId));
                    return Task.FromResult(policy.Build());
                }
                return Task.FromResult<AuthorizationPolicy>(null);
            }
        }

    Over18Handler

        public class Over18Handler : AuthorizationHandler<Over18Requirement>
        {
            protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                           Over18Requirement  requirement)
            {
                if (requirement.ActivityId=="1001")
                {
                    context.Succeed(requirement);
                }
                return Task.CompletedTask;
            }
        }

    Controller

    	[CustomAuthorize(Policy = "Over18", ActivityId = "1001")]
            public IActionResult Index()
            {
                return View("Index");
    	}
    	[CustomAuthorize(Policy = "Over18", ActivityId = "1002")]
    	public IActionResult test1()
    	{
    	    return View();
    	}
    	public IActionResult test()
    	{
    	    return View();
    	}

    Here is the result. 

    Best Regards,

    YihuiSun

    Tuesday, June 1, 2021 8:54 AM