Получить строковое значение из Enum в .net Core Authorize Attribute - PullRequest
0 голосов
/ 08 июля 2019

У меня есть приложение MVC на основе политики .net, в котором только авторизованный пользователь имеет доступ к какому-либо конкретному меню.Я использовал атрибут [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")].Можно ли каким-либо образом обобщить атрибут Authorize с помощью Enum?

Ответы [ 2 ]

2 голосов
/ 08 июля 2019

У меня есть метод расширений, и я использую его для чтения имени атрибута дисплея

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

И вы можете использовать его таким образом, замените атрибут Description атрибутом DisplayAttribute и установите правильное имя


public enum MenuEnum
    {
        [Display(Name="Menu1")]
        Dashboard,
        [Display(Name="Menu2")]
        Help,
        [Display(Name="Menu3")]
        About
    }
[Authorize(Policy=MenuEnum.About.ToDisplay())]
1 голос
/ 09 июля 2019

Вы можете реализовать свой собственный 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. Авторизация на основе строкового значения из Enum

[AuthorizeMenuPolicy(MenuEnum.Dashboard)]
...