Ролевая авторизация с наследованием контроллера - PullRequest
0 голосов
/ 27 августа 2018

Я работаю с ASP.NET Core 2.1

У меня есть абстрактный базовый класс для моих контроллеров, который имеет базовую реализацию для операций CRUD.Мы стремимся ограничить большинство из них так, чтобы их можно было вызывать только для некоторых пользователей (скажем, для тех, у кого есть роль администратора), но разрешать кому-то эту роль для всех или для другой роли.

Будет ли это работать как-то так?

[Authorize(Roles = "Admin")]
abstract class BaseController<T> : Controller
{
    public virtual IActionResult GetAll() { }
    public virtual IActionResult Create(T entity) { }
    public virtual IActionResult Read(int id) { }
    public virtual IActionResult Delete(int key) { }
}

[Authorize(Roles = "ClassRole")]
class EntityController : BaseController<Entity>
{
    [AllowAnonymous]
    public override IActionResult GetAll() { } //callable by anyone?

    //Create not overriden so callable only by Admins (and/or ClassRole?)

    public override IActionResult Read() //overridden but no attribute so ClassRole?

    [Authorize(Roles = "MehodRole")]
    public override IActionResult Delete() { } //all 3 (Admin, ClassRole, MethodRole) or something?
}

Это становится безумнее, только если в базовом классе также есть другие атрибуты Authorize и несколько ролей в одном атрибуте и т. Д.

Спасибо

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Редактировать: Как подсказал ОП, я неправильно понял его вопрос.

Если вы не хотите использовать несколько атрибутов авторизации, вы должны использовать пользовательские политики.Вы можете найти образец здесь .Затем вы можете просто использовать один атрибут авторизации с политикой.

[Authorize(Policy = "MyRoleRequirementPolicy")]

В рамках этой политики вы проверяете необходимые роли.Вы можете иметь даже большую логику, чем для аутентификации.В коде запуска вы просто добавляете подобные политики

services.AddAuthorization(options =>
{
    options.AddPolicy("MyRoleRequirementPolicy", policy =>
        policy.Requirements.Add(new CheckRolesPolicy(role1, role2, role3))); // you can register them with multiple roles under different names as often as you want
});

Такое поведение всегда можно использовать в базовой реализации.Если вы добавите другой атрибут к производному контроллеру или к определенной конечной точке, базовое поведение будет игнорироваться.

Почему я считаю наследование плохой идеей в этом случае:

  1. У вас никогда не будет одинаковых конечных точек для всего.
  2. Вы не должны передавать сущности контроллеру, контроллер вообще не должен ничего знать о сущностях, и вы захотите иметь разные типы моделей с разными свойствами длябыть более гибким и иметь меньшие данные, передаваемые, например, когда вы создаете новую сущность или просто исправляете некоторые поля существующей сущности
  3. Вы должны ввести поведение, подобное покою, чтобы быть более наглядным, если какая-то третья сторонаРазработчик в какой-то момент будет использовать ваш API.Конечно, вы все еще можете сделать это через описание маршрутизации
  4. Наследование не всегда правильно, особенно здесь это не так.Делая это, вы скрываете детали.Другой разработчик может скопировать ваш код, пока он не хочет авторизации.Некоторые вещи должны быть явными, а не неявными.Найти баланс между этим иногда не самая простая задача.

Это только мое мнение.То, что вы делаете, зависит от вас:)

Предыдущий ответ: Я бы не советовал использовать базовый контроллер с атрибутом Authorize.В любом случае, вы можете иметь несколько атрибутов авторизации для функции

[Authorize(Roles = "Admin")]
[Authorize(Roles = "ClassRole")]
[Authorize(Roles = "MehodRole")]
public override IActionResult Delete() { }
0 голосов
/ 27 августа 2018

Если вы используете Identity, вы можете легко, но если вы хотите настроить аутентификацию по ролям, вы можете проверить эту статью https://docs.microsoft.com/tr-tr/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.1

...