【问题标题】:Get String value from Enum in .net core Authorize Attribute从.net核心授权属性中的枚举获取字符串值
【发布时间】:2019-07-09 18:01:09
【问题描述】:

我有一个基于策略的 .net 核心 MVC 应用程序,其中只有授权用户才能访问任何特定菜单。我为每个控制器使用了[Authorize(Policy = "MenuName")] 属性。但我想用一个Enum 来概括它,其中所有菜单都列在一个Enum 中,并在Authorize 属性中使用它而不是静态字符串("MenuName")。

public enum MenuEnum
    {
        [Description("Menu1")]
        Dashboard,
        [Description("Menu2")]
        Help,
        [Description("Menu3")]
        About
    }

我想像[Authorize(Policy = MenuEnum.Dashboard)] 一样使用它,而不是静态字符串[Authorize(Policy = "Dashboard")]。我们有什么方法可以用 Enum 泛化 Authorize 属性吗?

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc asp.net-core-2.1


    【解决方案1】:

    我有一个扩展方法,我用它来读取显示属性的名称

            public static string ToDisplay(this Enum value, DisplayProperty property = DisplayProperty.Name)
            {
    
                var attribute = value.GetType().GetField(value.ToString())
                    .GetCustomAttributes<DisplayAttribute>(false).FirstOrDefault();
    
                if (attribute == null)
                    return value.ToString();
    
                var propValue = attribute.GetType().GetProperty(property.ToString()).GetValue(attribute, null);
                return propValue.ToString();
            }
    

    你可以这样使用它 用 DisplayAttribute 替换 Description 属性并设置属性名称

    
    public enum MenuEnum
        {
            [Display(Name="Menu1")]
            Dashboard,
            [Display(Name="Menu2")]
            Help,
            [Display(Name="Menu3")]
            About
        }
    
    [Authorize(Policy=MenuEnum.About.ToDisplay())]
    

    【讨论】:

    • 感谢您的回复。你能告诉我什么是DisplayProperty吗?我需要添加任何参考吗?
    • 您必须使用 System.ComponentModel.DataAnnotations 命名空间才能使用 DisplayAttribute。您可以使用此link 获得帮助。如果我回答了你的问题的正确答案,请选择我的答案作为正确答案;)
    【解决方案2】:

    您可以实现自己的 AuthorizeAttribute。

    1.AuthorizeMenuPolicyAttribute

     public class AuthorizeMenuPolicyAttribute : TypeFilterAttribute
    {
        public AuthorizeMenuPolicyAttribute(MenuEnum Policy) : base(typeof(AuthorizeMenuPolicyFilter))
        {
            Arguments = new object[] { Policy };
        }
    }
    

    2.AuthorizeMenuPolicyFilter

     public class AuthorizeMenuPolicyFilter: IAsyncAuthorizationFilter
    {
        private readonly IAuthorizationService _authorization;
        public MenuEnum _policy { get;  set; }
        public AuthorizeMenuPolicyFilter(MenuEnum policy, IAuthorizationService authorization)
        {
            _policy = policy;
            _authorization = authorization;
        }
    
        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            string description = GetEnumDescription(_policy);
    
            var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, description);
            if (authorized.Succeeded)
            {
                return;
            }
           context.Result = new ForbidResult();
           return;
    
        }
    
        public static string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
    
            DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
    
            if (attributes != null && attributes.Any())
            {
                return attributes.First().Description;
            }
    
            return value.ToString();
        }
    }
    

    3.在启动时添加你想要的策略

    services.AddAuthorization(options =>
            {
                options.AddPolicy("Menu1", policy =>
                        policy.RequireAssertion(context =>
                            context.User.HasClaim(c => c.Type == "menu1")));
    
            });
    

    4.基于来自枚举的字符串值的授权

    [AuthorizeMenuPolicy(MenuEnum.Dashboard)]
    

    【讨论】:

      猜你喜欢
      • 2013-08-14
      • 1970-01-01
      • 2022-01-22
      • 2011-02-16
      • 2013-07-18
      • 2020-07-11
      • 2021-04-04
      • 2010-12-20
      相关资源
      最近更新 更多