How ToT2 Dark_1200x303

Авторизация в ASP.NET Core контролируется с помощью AuthorizeAttribute и различных параметров. В самой простой форме, применении [Authorize] атрибута к контроллеру, действию или Razor странице, ограничивает доступ к этому компоненту пользователям, прошедшим проверку подлинности. Сегодня я опишу, каким образом добавить свои атрибуты.

В ASP.NET Core MVC авторизация выполняется с помощью класса AuthorizeAttribute. Вот простой пример использования авторизации на основе ролей:

[pastacode lang=»c» manual=»%5BAuthorize(Roles%20%3D%20%22Admin%2CModerator%22)%5D%0Apublic%20class%20AdminController%20%3A%20Controller%0A%7B%0A%20%20%20%20%2F%2F%20…%20%0A%7D%0A» message=»» highlight=»» provider=»manual»/]

Пользователи с ролью администратора или модератора будут иметь доступ к действиям в AdminController.

Хотя в этом нет ничего плохого и он выполняет свою работу, строка «Администратор, модератор», как вы можете себе представить, является хорошим рецептом для опечатки. Итак, давайте переместим имена ролей в набор строковых констант:

[pastacode lang=»c» manual=»public%20static%20class%20RoleConstants%0A%7B%0A%20%20%20%20public%20const%20string%20Admin%20%3D%20%22Admin%22%3B%0A%20%20%20%20public%20const%20string%20Moderator%20%3D%20%22Moderator%22%3B%0A%20%20%20%20%2F%2F%20more%20roles%0A%7D%0A» message=»» highlight=»» provider=»manual»/]

AdminController теперь будет выглядеть следующим образом:

[pastacode lang=»c» manual=»%5BAuthorize(Roles%3DRoleConstants.Admin%2B%22%2C%22%2BRoleConstants.Moderator)%5D%0Apublic%20class%20AdminController%20%3A%20Controller%0A%7B%0A%20%20%20%20%2F%2F%20…%20%0A%7D%0A» message=»» highlight=»» provider=»manual»/]

Я знаю, что не идеально. К сожалению, мы не можем использовать интерполированные строки, такие как $ «{RoleConstants.Admin}, {RoleConstants.Moderator}» с атрибутами.

Это хороший пример того, как расширение класса AuthorizeAttribute может пригодится. Поскольку мы пытаемся упростить вызов авторизации на основе ролей для контроллера или действия, давайте создадим настраиваемый атрибут AuthorizeByRoleAttribute:

[pastacode lang=»c» manual=»%2F%2F%2F%20%3Csummary%3E%0A%2F%2F%2F%20Specifies%20that%20the%20class%20or%20method%20that%20this%20attribute%20is%20applied%20to%20requires%20role-based%20authorization.%20%3Cbr%20%2F%3E%0A%2F%2F%2F%20To%20authorize%20users%20with%20either%20role%20A%20or%20role%20B%2C%20use%3A%0A%2F%2F%2F%20%3Ccode%3E%0A%2F%2F%2F%20%5BAuthorizeByRole(%22A%22%2C%20%22B%22)%5D%0A%2F%2F%2F%20%3C%2Fcode%3E%0A%2F%2F%2F%20To%20only%20authorize%20users%20with%20both%20role%20A%20and%20role%20B%2C%20use%3A%0A%2F%2F%2F%20%3Ccode%3E%0A%2F%2F%2F%20%5BAuthorizeByRole(%22A%22)%5D%20%3Cbr%20%2F%3E%0A%2F%2F%2F%20%5BAuthorizeByRole(%22B%22)%5D%0A%2F%2F%2F%20%3C%2Fcode%3E%0A%2F%2F%2F%20%3C%2Fsummary%3E%0Apublic%20class%20AuthorizeByRoleAttribute%20%3A%20AuthorizeAttribute%0A%7B%0A%20%20%20%20public%20MyAuthorizeAttribute(params%20string%5B%5D%20roles)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20Roles%20%3D%20String.Join(%22%2C%22%2C%20roles)%3B%0A%20%20%20%20%7D%0A%7D%0A» message=»» highlight=»» provider=»manual»/]

Мы можем использовать его следующим образом:

[pastacode lang=»c» manual=»%5BAuthorizeByRole(RoleConstants.Admin%2C%20RoleConstants.Moderator)%5D%0Apublic%20class%20AdminController%20%3A%20Controller%0A%7B%0A%20%20%20%20%2F%2F%20…%20%0A%7D%0A» message=»» highlight=»» provider=»manual»/]

Намного лучше, правда?

Если вы работаете с полнофункциональной платформой ASP.NET MVC, вы знаете, как можно было переопределить методы из AuthorizeAttribute, чтобы добавить настраиваемое поведение авторизации. Вы не можете сделать это в ASP.NET Core. (Источник для ASP.NET MVC | Источник для ASP.NET Core)

Если вам нужно настраиваемое поведение авторизации, используйте политики. Барри Дорранс (Большой профи в безопасности ASP.NET в Microsoft) рассказывает об этом в подкасте .NET Rocks 2017 года, примерно 30-минутная отметка — стоит послушать, если вас интересует какая-то предыстория.

Вывод

Настроить [Authorize], расширив его, довольно просто, но имеет смысл только в том случае, если вы пытаетесь сделать код более удобным для сопровождения. Для настраиваемого поведения вместо этого вы можете использовать политики ASP.NET Core.