从.net核心中的枚举获取字符串值授权属性

时间:2019-07-08 11:13:44

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

我有一个基于策略的.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属性吗?

2 个答案:

答案 0 :(得分: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())]

答案 1 :(得分:1)

您可以实现自己的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)]