如何覆盖 ActionLink 行为

发布于 2024-10-28 05:33:04 字数 149 浏览 1 评论 0原文

好的,我想通过 ActionLink 方法为我的网站添加一些安全性。如果用户有足够的权限来访问操作/控制器,则 ActionLink 应呈现该链接。如果不是,它应该返回一个空字符串。现在,ActionLink 是一个静态方法,这使得一切变得更加困难。有什么办法可以实现我想做的事情吗?

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 link. If not, It should return an empty string. Now, the ActionLink is a static method and that makes it all more difficult. Is there any way to achieve what im trying to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

慢慢从新开始 2024-11-04 05:33:04

新的 AuthorizeActionLink 扩展方法。根据需要超载。

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;
}

在确定用户是否获得授权方面做肮脏工作的方法

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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文