Как вы реализовывали процесс авторизации в своих проектах?

«Как вы реализовывали процесс авторизации в своих проектах?» — вопрос из категории Безопасность, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В проектах на C# я использовал несколько подходов в зависимости от требований:

1. ASP.NET Core Identity для монолитных приложений и MVC:

  • Для чего: Полноценная система управления пользователями, ролями, входами через куки.
  • Как: Подключается через AddIdentity и AddEntityFrameworkStores.
  • Пример настройки:
    services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
  • Плюсы: Готовые UI-страницы (регистрация, логин), двухфакторная аутентификация, блокировка учетных записей.

2. JWT (JSON Web Tokens) для API и SPA/мобильных клиентов:

  • Для чего: Статистические токены для доступа к REST API без состояния сервера (stateless).
  • Как: Клиент получает токен после логина и отправляет его в заголовке Authorization: Bearer <token>.
  • Пример валидации токена в API:
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = _configuration["Jwt:Issuer"],
                    ValidateAudience = true,
                    ValidAudience = _configuration["Jwt:Audience"],
                    ValidateLifetime = true,
                    IssuerSigningKey = new SymmetricSecurityKey(
                        Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]))
                };
            });
  • Ключевой момент: Секретный ключ (Jwt:Key) должен храниться в безопасном месте (например, Azure Key Vault), а не в коде.

3. Авторизация на основе политик (Policy-based Authorization):

  • Для чего: Гибкое управление доступом на основе ролей, утверждений (claims) или сложной бизнес-логики.
  • Пример:

    // Определение политики в Startup/Program.cs
    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireAdminRole", policy =>
            policy.RequireRole("Admin"));
        options.AddPolicy("MinimumAge", policy =>
            policy.RequireClaim("DateOfBirth")
                   .Requirements.Add(new MinimumAgeRequirement(18)));
    });
    
    // Использование на контроллере или методе
    [Authorize(Policy = "RequireAdminRole")]
    public class AdminController : Controller { }

4. Внешние провайдеры (OAuth 2.0 / OpenID Connect):

  • Для чего: Вход через Google, Microsoft, GitHub и т.д.
  • Как: Использование пакетов Microsoft.AspNetCore.Authentication.Google и настройка callback URL.

Обязательные меры безопасности:

  • Всегда использовать HTTPS в продакшене.
  • Хешировать пароли с помощью стойких алгоритмов (PBKDF2, BCrypt, Argon2).
  • Защищать от CSRF-атак с помощью AntiForgeryToken в формах.
  • Для JWT устанавливать разумное время жизни токена (обычно 15-60 минут) и использовать механизм Refresh Tokens для его обновления.