How ToT2 Dark_1200x303

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

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

[Authorize(Roles = "Admin,Moderator")]
public class AdminController : Controller
{
    // ... 
}

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

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

public static class RoleConstants
{
    public const string Admin = "Admin";
    public const string Moderator = "Moderator";
    // more roles
}

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

[Authorize(Roles=RoleConstants.Admin+","+RoleConstants.Moderator)]
public class AdminController : Controller
{
    // ... 
}

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

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

/// <summary>
/// Specifies that the class or method that this attribute is applied to requires role-based authorization. <br />
/// To authorize users with either role A or role B, use:
/// <code>
/// [AuthorizeByRole("A", "B")]
/// </code>
/// To only authorize users with both role A and role B, use:
/// <code>
/// [AuthorizeByRole("A")] <br />
/// [AuthorizeByRole("B")]
/// </code>
/// </summary>
public class AuthorizeByRoleAttribute : AuthorizeAttribute
{
    public MyAuthorizeAttribute(params string[] roles)
    {
        Roles = String.Join(",", roles);
    }
}

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

[AuthorizeByRole(RoleConstants.Admin, RoleConstants.Moderator)]
public class AdminController : Controller
{
    // ... 
}

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

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

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

Вывод

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