【问题标题】:How to visually separate security-trimmed action links in ASP.NET MVC如何在 ASP.NET MVC 中直观地分离安全修剪的操作链接
【发布时间】:2010-02-22 15:37:57
【问题描述】:

我正在尝试在 ASP.NET MVC 中使用经过安全调整的操作链接,并且正在考虑使用 SecurityTrimmedActionLink 辅助方法 described here(进行一些修改)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using System.Web.Routing;
using System.Web.Mvc;
using System.Collections;
using System.Reflection;
namespace System.Web.Mvc.Html
{
    public static class HtmlHelperExtensions
    {
        public static string SecurityTrimmedActionLink(
        this HtmlHelper htmlHelper,
        string linkText,
        string action,
        string controller)
        {
            return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, false);
        }
        public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, bool showDisabled)
        {
            if (IsAccessibleToUser(action, controller))
            {
                return htmlHelper.ActionLink(linkText, action, controller);
            }
            else
            {
                return showDisabled ? String.Format("<span>{0}</span>", linkText) : "";
            }
        }
        public static bool IsAccessibleToUser(string actionAuthorize, string controllerAuthorize)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            GetControllerType(controllerAuthorize);
            Type controllerType = GetControllerType(controllerAuthorize);
            var controller = (IController)Activator.CreateInstance(controllerType);
            ArrayList controllerAttributes = new ArrayList(controller.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true));
            ArrayList actionAttributes = new ArrayList();
            MethodInfo[] methods = controller.GetType().GetMethods();
            foreach (MethodInfo method in methods)
            {
                object[] attributes = method.GetCustomAttributes(typeof(ActionNameAttribute), true);
                if ((attributes.Length == 0 && method.Name == actionAuthorize) || (attributes.Length > 0 && ((ActionNameAttribute)attributes[0]).Name == actionAuthorize))
                {
                    actionAttributes.AddRange(method.GetCustomAttributes(typeof(AuthorizeAttribute), true));
                }
            }
            if (controllerAttributes.Count == 0 && actionAttributes.Count == 0)
                return true;

            IPrincipal principal = HttpContext.Current.User;
            string roles = "";
            string users = "";
            if (controllerAttributes.Count > 0)
            {
                AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute;
                roles += attribute.Roles;
                users += attribute.Users;
            }
            if (actionAttributes.Count > 0)
            {
                AuthorizeAttribute attribute = actionAttributes[0] as AuthorizeAttribute;
                roles += attribute.Roles;
                users += attribute.Users;
            }

            if (string.IsNullOrEmpty(roles) && string.IsNullOrEmpty(users) && principal.Identity.IsAuthenticated)
                return true;

            string[] roleArray = roles.Split(',');
            string[] usersArray = users.Split(',');
            foreach (string role in roleArray)
            {
                if (role == "*" || principal.IsInRole(role))
                    return true;
            }
            foreach (string user in usersArray)
            {
                if (user == "*" && (principal.Identity.Name == user))
                    return true;
            }
            return false;
        }

        public static Type GetControllerType(string controllerName)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            foreach (Type type in assembly.GetTypes())
            {
                if (type.BaseType.Name == "Controller" && (type.Name.ToUpper() == (controllerName.ToUpper() + "Controller".ToUpper())))
                {
                    return type;
                }
            }
            return null;
        }
    }
}

我想做的是在每个链接之间放置一个竖线,如下所示:

link1 | link2 | link3

但是如果链接已被修剪掉,我不希望在链接之间出现两个竖线(辅助方法将返回一个空字符串),如果没有链接或只有链接,则根本不能有任何竖线出现一个链接。 SecurityTrimmedActionLink 辅助方法无法辅助竖线;它不会知道其他链接。

这可以通过视图中的一些简单逻辑来实现吗?

【问题讨论】:

标签: c# asp.net-mvc security role-based


【解决方案1】:

经过一番思考,我创建了一个新的HtmlHelper 方法:

using System.Text;

namespace System.Web.Mvc.Html
{
    public static class HtmlHelpers
    {
        public static string Delimit(
             this HtmlHelper h, string delimiter, params string[] s)
        {
            bool flag = false;
            StringBuilder b = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
                if (s[i].Length > 0)
                    if (flag)
                        b.Append(delimiter + s[i]);
                    else
                    {
                        flag = true;
                        b.Append(s[i]);
                    }
            return b.ToString();
        }
    }
}

这应该允许我写:

<% =Html.Delimit("|", 
        Html.SecurityTrimmedActionLink(...),
        Html.SecurityTrimmedActionLink(...),
        ...
    ); 
$>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    相关资源
    最近更新 更多