Set AuthorizeAttribute to disable users by default if Roles are empty

I am pretty surprised at the default behavior of AuthorizeAttribute ; if you did not provide it with any Roles property, it simply allows any authorized user to access the controller / action. Instead, I want to use the whitelist; if Roles is empty or empty, deny access to all users. How to do it?

+4
source share
2 answers

Here is what I came up with, in the end, as a filter, I add to the collection of global filters for the MVC application:

 /// <summary> /// This filter should be applied to an MVC application as a global filter in RegisterGlobalFilters, not applied to individual actions/controllers. /// It will cause access to every action to be DENIED by default. /// If an AllowAnonymousAttribute is applied, all authorization checking is skipped (this takes precedence over AuthorizeSafeAttribute). /// If an AuthorizeSafeAttribute is applied, only the roles specified in AuthorizeSafeAttribute Roles property will be allowed access. /// </summary> public sealed class AuthorizeSafeFilter : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (!string.IsNullOrEmpty(this.Roles) || !string.IsNullOrEmpty(this.Users)) { throw new Exception("This class is intended to be applied to an MVC application as a global filter in RegisterGlobalFilters, not applied to individual actions/controllers. Use the AuthorizeSafeAttribute with individual actions/controllers."); } // Disable caching for this request filterContext.HttpContext.Response.Cache.SetNoServerCaching(); filterContext.HttpContext.Response.Cache.SetNoStore(); // If AllowAnonymousAttribute applied, skip authorization if ( filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) ) { return; } // Backup original roles string rolesBackup = this.Roles; // Look for AuthorizeSafeAttribute roles bool foundRoles = false; string foundRolesString = null; object[] actionCustomAttributes = filterContext.ActionDescriptor.GetCustomAttributes(false); object[] controllerCustomAttributes = filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(false); if (actionCustomAttributes.Any(attr => attr is AuthorizeSafeAttribute)) { AuthorizeSafeAttribute foundAttr = (AuthorizeSafeAttribute)(actionCustomAttributes.First(attr => attr is AuthorizeSafeAttribute)); foundRoles = true; foundRolesString = foundAttr.Roles; } else if (controllerCustomAttributes.Any(attr => attr is AuthorizeSafeAttribute)) { AuthorizeSafeAttribute foundAttr = (AuthorizeSafeAttribute)(controllerCustomAttributes.First(attr => attr is AuthorizeSafeAttribute)); foundRoles = true; foundRolesString = foundAttr.Roles; } if (foundRoles && !string.IsNullOrWhiteSpace(foundRolesString)) { // Found valid roles string; use it as our own Roles property and auth normally this.Roles = foundRolesString; base.OnAuthorization(filterContext); } else { // Didn't find valid roles string; DENY all access by default filterContext.Result = new HttpUnauthorizedResult(); } // Restore original roles this.Roles = rolesBackup; } } 

I also define this attribute:

 /// <summary> /// Represents an attribute that is used to restrict access by callers to an action method, in conjunction /// with a global AuthorizeSafeFilter, DENYING all access by default. /// </summary> public class AuthorizeSafeAttribute : Attribute { public string Roles { get; set; } } 

I apply AllowAnonymousAttribute to my actions / login controllers and AuthorizeSafeAttribute to others, but if I forget to apply them, access will be denied by default. I want ASP.NET MVC to be as safe as this by default. :-)

+2
source
 public class AuthorizeExAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { if (string.IsNullOrWhiteSpace(Roles)) return false; return base.AuthorizeCore(httpContext); } } 

Now use [AuthorizeEx] on your controllers / actions

+3
source

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


All Articles