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

Ответ

В проектах на 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 для его обновления.

Ответ 18+ 🔞

Да ты посмотри, какие у нас тут подходы развелись, как грибов после дождя! Сижу я, значит, ковыряюсь в своих C# проектах, и понимаю — авторизация-то везде нужна, но везде по-разному, блядь. Ну, как с машинами: для дачи — «жигули», а если на работу в офис — уже что-то приличнее надо.

1. ASP.NET Core Identity — наш бронепоезд для монолитов. Это когда у тебя всё в одной куче: и база, и логика, и эти ваши MVC-странички. Зачем выёбываться? Берёшь эту штуку, и она тебе сразу делает:

  • Пользователей с ролями.
  • Вход через куки (помнишь, «запомнить меня»?).
  • Готовые странички регистрации и логина — хоть сейчас продавай. Настраивается проще пареной репы:
    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    Плюсы: Всё из коробки, хоть двухфакторку делай, хоть аккаунты блокируй. Но это как тяжелый танк — мощно, но для мобильных API или SPA он уже слишком неповоротливый, жрёт ресурсы не по делу.

2. JWT (JSON Web Tokens) — наш лёгкий и быстрый наёмник для API. А вот это уже для современных дел: SPA (типа React, Vue), мобильные приложения или микросервисы, которые друг с другом болтают. Stateless, ёпта! Сервер не парится о сессиях.

  • Клиент логинится, получает токен (эту длинную строку, похожую на абракадабру) и потом каждый запрос с ним носит: Authorization: Bearer <token>.
  • Сервер его проверяет и говорит: «Проходи, друг». Настройка валидации выглядит так:
    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) — это святое! Не пихай его в appsettings.json и уж тем более в код, а то будет тебе хиросима. Кидай его в Azure Key Vault или в секреты окружения, а то потом будешь руками лицо хватать.

3. Авторизация на политиках (Policy-based) — когда ролей уже мало. Бывает, что просто «админ» или «юзер» — это как молотком микрохирургию делать. Нужна точность! Хочешь, чтобы доступ был только у тех, кому есть 18, или кто из определённого отдела? Вот тебе политики.

services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdminRole", policy =>
        policy.RequireRole("Admin")); // Старое доброе
    options.AddPolicy("MinimumAge", policy =>
        policy.RequireClaim("DateOfBirth")
               .Requirements.Add(new MinimumAgeRequirement(18))); // А вот это уже серьёзно
});

[Authorize(Policy = "MinimumAge")]
public IActionResult BuyVodka() { ... }

Гибко, мощно, можно свою логику в требования впихнуть. Главное — не переусердствовать, а то получится такая паутина из политик, что сам черт ногу сломит.

4. Вход через левые сервисы (OAuth 2.0 / OpenID Connect). Лень своих пользователей заводить? Ну и не надо! Пусть заходят через Google, Microsoft или GitHub. Подключаешь пачку Microsoft.AspNetCore.Authentication.Google, настраиваешь callback URL (это важно, ато работать не будет), и вуаля — пользователи текут рекой. Люди сейчас вообще свои пароли забыли, им лишь бы одной кнопкой тыкнуть.

И напоследок, про безопасность, ёпта! Это не просто слова, это как ремень пристегнуть:

  • HTTPS в продакшене — обязательно. Иначе все твои токены и пароли будут лететь по воздуху как голые мужики по проспекту.
  • Пароли хешируй нормально — PBKDF2, BCrypt, Argon2. Никаких MD5 или SHA-1, это уже смех, а не защита.
  • CSRF-атаки лови с помощью AntiForgeryToken в формах. Без него какой-нибудь ушлёпок может от твоего имени заказ на миллион сделать.
  • Для JWT не делай токены вечными. Давай им жить 15-60 минут, а для обновления используй Refresh Tokens. Иначе, если токен утечёт, пиши пропало — доступ будет у злоумышленника до скончания веков.

Вот так вот, коротко и без лишней воды. Выбирай инструмент под задачу, не тупи, и безопасность не забудь — потом меньше головной боли будет, ей-богу.