How to extend AuthorizeAttribute and check user roles

I'm busy writing my own custom attribute for my action method called MyAuthorizeAttribute, I'm still busy writing code, here is my incomplete code:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class MyAuthorizeAttribute : AuthorizeAttribute { public new Role Roles; public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (Roles != 0) // Did it this way to see what the value of Roles was return; // Here I am going to get a list of user roles // I'm doing my own database calls filterContext.Result = new HttpUnauthorizedResult(); } } 

Here is my role enumeration:

 public enum Role { Administrator = 1, SuperAdministrator = 2 } 

My action method:

 [MyAuthorize(Roles = Role.Administrator|Role.SuperAdministrator)] public ActionResult Create() { return View(); } 

The reason I did not use Roles = "Administrator, SuperAdministrator" is because the roles are hard-coded. I do not want to have 100 places to change if the role name changes.

Given my method, when it comes to if (Roles! = 0), the total Roles value is 3, how would I check if these 2 roles are included in the list of user roles for a particular user?

Am I doing it right here? If not, how could I implement this? It should not be the way I did it.

+4
source share
2 answers

It would not be better if MyAuthorizeAttribute accepted an IList (or similar) that way, it is typical, but you don't need to use bit flags. Bit flags are great if you want to keep the result, but this is a different way.

Edit (now with examples):

 Attribute: [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class MyAuthorizeAttribute : AuthorizeAttribute { public Role[] RoleList { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("httpContext"); } IPrincipal user = httpContext.User; if (!user.Identity.IsAuthenticated) { return false; } //Only role access is implemented here /*if ((this._usersSplit.Length > 0) && !this._usersSplit.Contains<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) { return false; }*/ if ((RoleList.Length > 0) && !RoleList.Select(p=>p.ToString()).Any<string>(new Func<string, bool>(user.IsInRole))) { return false; } return true; } } 

Controller:

 [MyAuthorize(RoleList = new []{Role.Administrator , Role.SuperAdministrator} )] public ActionResult Create() { return View(); } 
+4
source

If I understood correctly, your problem here is not in the inheritance of AuthorizeAttribute , but in comparing the enum values. You probably need an enum type that can be used as a bit flag. If so, see the section on enumeration types in the C # Programming Guide, especially the second part, "Enumeration Types as Bit Flags."

To clarify a bit:

Instead of checking Roles!=0 you can now do something like this:

 public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); // Here you get an enum indicating the roles this user is in. The method // converts the db information to a Role enum before it is returned. // If the user is not authenticated, the flag should not be set, ie equal 0. Role userRole = GetUserRolesFromDatabase(); // Bitwise comparison of the two role collections. if (Roles & userRole > 0) { // The user is in at least one of the roles in Roles. Return normally. return; } // If we haven't returned yet, the user doesn't have the required privileges. new HttpUnauthorizedResult(); } 

To simplify the comparison, you can use the following extension method for your enumeration:

 public static class RolesExtensions { public static bool HasAnyOf(this Roles r1, Roles roles) { return (r1 & roles) > 0; } } 
+2
source

Source: https://habr.com/ru/post/1341296/


All Articles