Authorize Attribute with Multiple Roles

前端 未结 5 1290
长发绾君心
长发绾君心 2020-12-02 07:00

I would like to add Authorization to a controller, for multiple Roles at once.

Normally that would look like this:

[Authorize(Roles = \"RoleA,RoleB,R         


        
相关标签:
5条回答
  • 2020-12-02 07:02

    I feel like a custom authorize attribute is overkill for this issue unless you have a large amount of roles.

    Since the string must be known at compile time, why not make a static Role class that contains public strings of the roles you have defined, and then add comma separated strings with certain roles that you want to authorize:

    public static class Roles
    {
        public const string ADMIN = "Admin";
        public const string VIEWER = "Viewer";
    
        public const string ADMIN_OR_VIEWER = ADMIN + "," + VIEWER;
    }
    

    And then you can use the Authorize Attribute like so on the Controller Class or the Controller Method (or both):

    [Authorize(Roles = Roles.ADMIN]
    public class ExampleController : Controller
    {
        [Authorize(Roles = Roles.ADMIN_OR_VIEWER)
        public ActionResult Create()
        {
            ..code here...
        }
    }
    
    0 讨论(0)
  • 2020-12-02 07:04

    The best and simplest way I found to resolve this problem is just to concatenate roles in the Authorize attribute.

    [Authorize(Roles = CustomRoles.Admin + "," + CustomRoles.OtherRole)]
    

    with CustomRole a class with constant strings like this :

    public static class CustomRoles
    {
        public const string Admin = "Admin";
        // and so on..
    }
    
    0 讨论(0)
  • 2020-12-02 07:13

    Make sure you are deriving your custom attribute class off System.Web.Mvc.AuthorizeAttribute and NOT System.Web.Http.AuthorizeAttribute.

    I ran into the same problem. Once I changed it, everything worked.

    You may also want to add the following to your custom attribute class:

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] 
    
    0 讨论(0)
  • 2020-12-02 07:20

    What i did is the answer in @Tieson

    I tweak a little in his answer. Instead of string.Join why not convert it to list?

    Here is my answer:

    public class AuthorizeRolesAttribute : AuthorizeAttribute
    {
        private new List<string> Roles;
        public AuthorizeRolesAttribute(params string[] roles) : base()
        {
            Roles = roles.toList()
        }
    }
    

    And then check the if the role is valid overriding OnAuthorization

    public override void OnAuthorization(HttpActionContext actionContext)
    {
                if (Roles == null)
                    HandleUnauthorizedRequest(actionContext);
                else
                {
                    ClaimsIdentity claimsIdentity = HttpContext.Current.User.Identity as ClaimsIdentity;
                    string _role = claimsIdentity.FindFirst(ClaimTypes.Role).Value;
                    bool isAuthorize = Roles.Any(role => role == _role);
    
                    if(!isAuthorize)
                        HandleUnauthorizedRequest(actionContext);
                }
            }
    

    And there you have it, it is now validating if the role is authorized to access the resource

    0 讨论(0)
  • 2020-12-02 07:21

    Try to create custom authorize attribute like this.

    public class AuthorizeRolesAttribute : AuthorizeAttribute
    {
        public AuthorizeRolesAttribute(params string[] roles) : base()
        {
            Roles = string.Join(",", roles);
        }
    }
    

    Assuming your roles will be the same for multiple controllers, create a helper class:

    public static class Role
    {
        public const string Administrator = "Administrator";
        public const string Assistant = "Assistant";
    }
    

    Then use it like so:

    public class MyController : Controller
    {
        [AuthorizeRoles(Role.Administrator, Role.Assistant)]
        public ActionResult AdminOrAssistant()
        {                       
            return View();
        }
    }
    
    0 讨论(0)
提交回复
热议问题