0

I was trying to implement policy-based authorization on ASP.NET MVC 5 and I was able to make it work (with this).

But I'd like to replace the magic strings like in the following example...

[PolicyAuthorize(Policy = "Admin")]
        public ActionResult Index()
        {
            return View();
        }

... with Enums somewhat like this:

[PolicyAuthorize(Policy.Admin & Policy.Owner)]
        public ActionResult Index()
        {
            return View();
        }

I've read on this post that it can be done by creating a custom attribute with the following example but I just can't figure out how to implement it properly:

public class AuthorizeRoles : AuthorizeAttribute
{
    public AuthorizeRoles(params MyEnum[] roles)
    {
        ...
    }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        ...
    }
}

That's the custom ResourceAuthorizeAttribute I made for that:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class PolicyAuthorizeAttribute : Microsoft.Owin.Security.Authorization.Mvc.ResourceAuthorizeAttribute
{
    public Policy[] Policies { get; }

    public PolicyAuthorizeAttribute(params Policy[] policies)
    {

    }

    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

My Policy Enum:

public enum Policy
{
    Admin = 1,
    Office = 2,
    Teacher = 3,
    Student = 4,
    Owner = 5
}

My Startup class wuth the policies:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);

        app.UseAuthorization(options =>
        {
            options.AddPolicy(Policy.Admin.ToString(), policy => policy.RequireRole(Rolle.Admin.ToString()));
            options.AddPolicy(Policy.Office.ToString(), policy => policy.RequireRole(Rolle.Office.ToString()));
            options.AddPolicy(Policy.Teacher.ToString(), policy => policy.RequireRole(Rolle.Teacher.ToString()));
            options.AddPolicy(Policy.Student.ToString(), policy => policy.RequireRole(Rolle.Student.ToString()));
            // still working on the following policy
            //options.AddPolicy(Policy.Owner.ToString(), policy => policy);
        });
    }
}

I'd be very grateful for any help!

Mazzmax
  • 7
  • 1
  • 4
  • Change your enums to powers of 2 like 1, 2, 4, 8, 16, 32, 64. This way and method will work. You are ANDing 1 & 5 which results in garbage. – jdweng Dec 13 '22 at 11:31
  • The accepted answer in the post you mentioned answers your question – theemee Dec 13 '22 at 11:33

0 Answers0