As mentioned in the previous section, AuthorizeAttribute can be used for permission management:
[Authorize] public ActionResult TestAuthorize() { return View(); } [Authorize(Users="test1,test2")] public ActionResult TestAuthorize() { return View(); } [Authorize(Roles="Admin")] public ActionResult TestAuthorize() { return View(); }
However, website permissions are not always the same. When a new role or role is added, you can only modify the corresponding features of each Action. When the project is large, you can imagine the workload. Fortunately, we can rewrite AuthorizeAttribute to achieve custom permission management. Create a CustomAuthorizeAttribute class to inherit from AuthorizeAttribute. Open AuthorizeAttribute to view the method description. We only need to rewrite AuthorizeCore and OnAuthorization to achieve our goal.
// Summary: // When overridden, provides an entry point for custom authorization checks. // // Parameters: // httpContext: // The HTTP context, which encapsulates all HTTP-specific information about // an individual HTTP request. // // Returns: // true if the user is authorized; otherwise, false. // // Exceptions: // System.ArgumentNullException: // The httpContext parameter is null. protected virtual bool AuthorizeCore(HttpContextBase httpContext);// // Summary: // Called when a process requests authorization. // // Parameters: // filterContext: // The filter context, which encapsulates information for using System.Web.Mvc.AuthorizeAttribute. // // Exceptions: // System.ArgumentNullException: // The filterContext parameter is null. public virtual void OnAuthorization(AuthorizationContext filterContext);
Reload the AuthorizeCore method in CustomAuthorizeAttribute. The processing logic is as follows: first, determine whether the current account is authenticated. If not, false is returned. Then, obtain the type of the current account, and compare with the given type. If the type is the same, true is returned; otherwise, false is returned. Generally, permission management on a website uses the permission tree to save the role permissions to a database or file. In this example, we use the XML file to save the role of each Action, in this way, when a user requests an Action, the XML file obtains the corresponding permissions of the Action, and then checks whether the account has the corresponding permissions. The CustomAuthorizeAttribute class code is as follows:
public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute { public new string[] Roles { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("HttpContext"); } if (!httpContext.User.Identity.IsAuthenticated) { return false; } if (Roles == null) { return true; } if (Roles.Length == 0) { return true; } if (Roles.Any(httpContext.User.IsInRole)) { return true; } return false; } public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext) { string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; string actionName = filterContext.ActionDescriptor.ActionName; string roles = GetRoles.GetActionRoles(actionName, controllerName); if (!string.IsNullOrWhiteSpace(roles)) { this.Roles = roles.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); } base.OnAuthorization(filterContext); } }
When a user requests an Action, the OnAuthorization method is called. In this method, GetRoles. getActionRoles (actionName, controllerName); search for the role types required by the current Action based on the Controller and Action. After obtaining the Roles of the Action, compare the Roles with the user role in AuthorizeCore. any (httpContext. user. isInRole). If you do not have the required permissions, the system returns false, and the program automatically jumps to the logon page.
GetRoles is an XML parsing class and the code is as follows:
public class GetRoles { public static string GetActionRoles(string action, string controller) { XElement rootElement = XElement.Load(HttpContext.Current.Server.MapPath("/")+"ActionRoles.xml"); XElement controllerElement = findElementByAttribute(rootElement, "Controller", controller); if (controllerElement != null) { XElement actionElement = findElementByAttribute(controllerElement, "Action", action); if (actionElement != null) { return actionElement.Value; } } return ""; } public static XElement findElementByAttribute(XElement xElement,string tagName, string attribute) { return xElement.Elements(tagName).FirstOrDefault(x => x.Attribute("name").Value.Equals(attribute,StringComparison.OrdinalIgnoreCase)); } }
Corresponding permission XMl file:
<?xml version="1.0" encoding="utf-8" ?><Roles> <Controller name="Home"> <Action name="Index"></Action> <Action name="About">Manager,Admin</Action> <Action name="Contact">Admin</Action> </Controller></Roles>
When the requirement changes, you only need to modify the XML file.
When using the filter, you only need to register the filter in Global. asax.
filters.Add(new CustomAuthorizeAttribute());
Of course, this is just a simple example. The actual application will be much more complicated. It may also need to be implemented in the out-of-the-box MemberShipProvider and RoleProvider