Получить роли, указанные в действии контроллера - PullRequest
0 голосов
/ 30 января 2020

У меня есть контроллер MVC и класс, который создает меню с элементами, которые должны отображаться только пользователям с определенной ролью c для действия контроллера. В приведенном ниже случае я не хочу отображать пункт меню Details для пользователей с Role2. В итоге я задаю те же роли в пунктах меню, те же роли, которые я уже указала на контроллерах. Таким образом, у меня есть 2 места, где я определяю роли, и они должны быть одинаковыми, так что это подвержено ошибкам.

То, что я хотел бы сделать, это как-то получить роли от контроллера, но я понятия не имею, как это сделать или, если это вообще возможно.

[Authorize(Roles = "Role1,Role2")]
public class MyController
{
    public IActionResult Index() 
    {
        return View();
    }

    [Authorize(Roles = "Role1")]
    public IActionResult Details(int? id) 
    {
        ...
        return View(...);
    }
}

public class MenuItem
{
    public string Action { get; set; }
    public string Controller { get; set; }
    public string Roles { get; set; }
}

...
var item = new MenuItem 
{ 
    Action = "Index", 
    Controller = "MyController", 
    Roles = "Role1,Role2",                                <---- this is what I do now.
    Roles = GetRoles(MyController.Index.AuthorizedRoles)  <---- this is what I need.
}; 

1 Ответ

1 голос
/ 30 января 2020

Как насчет этого заводского метода для вашего MenuItem:

public class MenuItem
{
    public string Action { get; private set; }
    public string Controller { get; private set; }
    public string Roles { get; private set; }

    private MenuItem() { }

    public static MenuItem For<TMethod>(TMethod method) where TMethod : Delegate
    {
        var methodInfo = method.GetMethodInfo();
        var attributes = methodInfo
            .GetCustomAttributes(typeof(AuthorizeAttribute))
            .Cast<AuthorizeAttribute>();

        // If no attribute is defined on the action method, check the controller itself
        if (attributes.Count() == 0)
        {
            attributes = methodInfo.DeclaringType
                .GetCustomAttributes(typeof(AuthorizeAttribute))
                .Cast<AuthorizeAttribute>();
        }

        return new MenuItem
        {
            Action = methodInfo.Name,
            Controller = methodInfo.DeclaringType.Name,
            Roles = string.Join(',', attributes.Select(a => a.Roles))
        };
    }
}

Это можно назвать как:

var menuItem = MenuItem.For<Func<IActionResult>>(MyController.Details);
...