How to override the ActionLink behavior

后端 未结 1 1378
轮回少年
轮回少年 2021-01-13 03:14

Ok, I want to add some security to my site via the ActionLink method. If the user has enough rights to access the action/controller then the ActionLink should render the lin

相关标签:
1条回答
  • 2021-01-13 03:55

    new AuthorizeActionLink extension method. Overload as needed.

    public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {
        if (HasActionPermission(helper, actionName, controllerName))
            return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
    
        return MvcHtmlString.Empty;
    }
    
    public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
    {
        if (HasActionPermission(helper, actionName, controllerName))
            return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
    
        return MvcHtmlString.Empty;
    }
    

    methods that do the dirty work in figuring out if the user is Authorized

    static bool HasActionPermission(this HtmlHelper htmlHelper, string actionName, string controllerName)
    {
        ControllerBase controllerToLinkTo = string.IsNullOrEmpty(controllerName)
            ? htmlHelper.ViewContext.Controller
            : GetControllerByName(htmlHelper, controllerName);
    
        ControllerContext controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerToLinkTo);
        ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerToLinkTo.GetType());
        ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
    
        return ActionIsAuthorized(controllerContext, actionDescriptor);
    }
    
    static bool ActionIsAuthorized(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        if (actionDescriptor == null)
            return false;
    
        AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
        foreach (IAuthorizationFilter authFilter in actionDescriptor.GetFilters().AuthorizationFilters)
        {
            authFilter.OnAuthorization(authContext);
    
            if (authContext.Result != null)
                return false;
        }
    
        return true;
    }
    
    static ControllerBase GetControllerByName(HtmlHelper helper, string controllerName)
    {
        IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
    
        IController controller = factory.CreateController(helper.ViewContext.RequestContext, controllerName);
    
        if (controller == null)
        {
            throw new InvalidOperationException(
                string.Format(
                    CultureInfo.CurrentUICulture,
                    "Controller factory {0} controller {1} returned null",
                    factory.GetType(),
                    controllerName));
        }
    
        return (ControllerBase)controller;
    }
    
    0 讨论(0)
提交回复
热议问题