Search code examples
asp.net-coreauthorizationasp.net-core-5.0authorize-attribute

Create a deny role attribute in .netcore 5.0


I want to create an attribute based on the authorize attribute that instead of granting a role access to an IActionResult it denies access.

I want to decorate the ActionResult with something like [Deny(Role="role")] so that if the role tries to access this it is redirected back to the refering url.

I have tried to modify the code below but a lot of the methods used do not exist in .netcore 5.0:

public class DenyAttribute : AuthorizeAttribute 
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return !base.AuthorizeCore(httpContext);
    }
}

Or

public class DenyByControllerActionAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var controller = httpContext.Request.RequestContext.RouteData.GetRequiredString("controller");
        var action = httpContext.Request.RequestContext.RouteData.GetRequiredString("action");
        var denyRole = string.Format("Deny{0}:{1}", controller, action);
        return !httpContext.User.IsInRole(denyRole) && base.AuthorizeCore(httpContext);
    }
}

How would go about creating something like the above code examples in .netcore 5.0 since the AuthorizeCore override no longer exist in .net 5.0?


Solution

  • In ASP.NET Core, you need implements Attribute and IAuthorizationFilter to custom authorize attribute:

    public class DenyAttribute : Attribute, IAuthorizationFilter
    {
        public string? Roles { get; set; }
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var originalUrl = context.HttpContext.Request.Headers["Referer"].ToString();
            var userInRole = context.HttpContext.User.IsInRole(Roles);
            if(userInRole)
            {
                context.Result = new RedirectResult(originalUrl);
            }
        }
    }
    

    Controller:

    [Deny(Roles = "yourRole")]
    public IActionResult Test()
    {
        return View();
    }