Аутентификация и авторизация

Материал из llmdocs — справочник разработчика
Аутентификация и авторизация
Аутентификация (AuthN)кто вы? — пароль, ключ, токен, биометрия
Авторизация (AuthZ)что вам можно? — роли, права, политики
Факторы аутентификациизнание, владение, свойство
Модели доступаACL, RBAC, ABAC, ReBAC
ПротоколыOAuth 2.0, OpenID Connect, SAML, WebAuthn (passkeys)
Типичные ошибкинарушение контроля доступа — первое место OWASP Top 10

Аутентификация (англ. authentication, сокращённо AuthN) — проверка подлинности: действительно ли пользователь, сервис или устройство тот, за кого себя выдаёт. Авторизация (authorization, AuthZ) — решение о том, какие действия разрешены уже установленному субъекту. Аутентификация отвечает на вопрос «кто вы?», авторизация — «что вам можно?». Перед ними иногда выделяют идентификацию — заявление о том, кто вы (ввод логина).

Аналогия: на проходной офиса охранник проверяет пропуск с фотографией — это аутентификация; то, что пропуск открывает только третий этаж, а серверную — нет, — авторизация. Путаница между понятиями закрепилась даже в протоколе HTTP: код 401 Unauthorized на самом деле означает «не аутентифицирован», а отказ в правах — это 403 Forbidden (см. Коды состояния HTTP).

Аутентификация

Факторы

Фактор Примеры
Знание пароль, PIN-код, ответ на секретный вопрос
Владение телефон с приложением-аутентификатором, аппаратный ключ, SIM-карта, закрытый ключ
Свойство (биометрия) отпечаток пальца, лицо, голос

Использование двух факторов разных типов — двухфакторная аутентификация — резко снижает риск взлома при утечке пароля.

Способы

  • Пароли. Хранятся на сервере только в виде медленного хеша с солью — bcrypt, scrypt, Argon2 (см. Хранение паролей (bcrypt, Argon2)). Современные рекомендации NIST — длинные пароли без принудительной периодической смены и без требований «обязательно цифра и спецсимвол», проверка по базам утёкших паролей.[1]
  • Passkeys и WebAuthn. Устройство хранит закрытый ключ, а сервер — открытый; вход подтверждается отпечатком или PIN-кодом устройства. Ключ привязан к домену сайта, поэтому фишинг не срабатывает (см. Криптография с открытым ключом).[6]
  • Одноразовые коды — TOTP в приложении, SMS (слабее из-за подмены SIM), ссылки на почту.
  • Вход через внешнего провайдера — OpenID Connect или SAML: приложение доверяет проверку личности провайдеру (Google, корпоративный каталог, VK ID).[7]
  • Для машин — ключи API, клиентские сертификаты (mTLS), ключи SSH, краткоживущие токены сервисных учётных записей.

Сессии и токены

После успешного входа нужно помнить пользователя между запросами, ведь HTTP не хранит состояние:

Сессия на сервере Самодостаточный токен (JWT)
Где состояние в хранилище сервера; клиенту — идентификатор в cookie в самом токене, подписанном сервером[5]
Отзыв мгновенный — удалить сессию сложен до истечения срока; нужны короткий срок и обновление
Масштабирование нужно общее хранилище сессий любой сервер проверяет подпись
Типичное применение веб-приложения API, связь между сервисами

Cookie сессии ставят с флагами HttpOnly, Secure и SameSite, защищаясь от кражи скриптом и CSRF (см. Cookie и сессии).

Авторизация

Модели доступа

  • ACL (списки контроля доступа) — у каждого объекта список, кому и что разрешено; так устроены права в файловых системах.
  • RBAC (ролевая модель) — права выдаются ролям (admin, editor, viewer), а роли — пользователям. Самая распространённая модель в приложениях.
  • ABAC (на основе атрибутов) — решение по правилам над атрибутами пользователя, ресурса и контекста: «менеджер может видеть заказы своего региона в рабочее время».
  • ReBAC (на основе отношений) — права следуют из связей: «редактировать документ может владелец и те, с кем он поделился»; так устроен доступ в Google Docs.

Как реализовывать

# проверка на сервере для каждого запроса, а не только скрытие кнопки в интерфейсе
@app.delete("/projects/{project_id}")
def delete_project(project_id: int, user: User = Depends(current_user)):
    project = repo.get(project_id) or raise_404()
    if project.owner_id != user.id and "admin" not in user.roles:
        raise HTTPException(status_code=403)
    repo.delete(project)

Главные правила:[3]

  1. Проверять на сервере при каждом запросе. Скрытая кнопка в интерфейсе — не защита: запрос можно отправить напрямую.
  2. Запрещено всё, что явно не разрешено (deny by default).
  3. Проверять доступ к конкретному объекту, а не только к типу операции. Классическая уязвимость IDOR: пользователь меняет в адресе /orders/1001 на /orders/1002 и видит чужой заказ.
  4. Минимальные права — и для людей, и для сервисов, и для ИИ-агентов (Принцип наименьших привилегий).
  5. Централизовать логику — одна библиотека или сервис политик вместо проверок, разбросанных по коду.

Нарушение контроля доступа занимает первое место в рейтинге самых распространённых уязвимостей веб-приложений OWASP Top 10.[4]

Типичные ошибки аутентификации

  • Сообщения, раскрывающие, существует ли пользователь («неверный пароль» вместо «неверный логин или пароль»).
  • Отсутствие ограничения попыток входа — подбор паролей.
  • Токены и ключи в коде, логах и URL; их место — в хранилище секретов (Управление секретами).
  • Самописная криптография и проверка JWT без проверки подписи и алгоритма. Надёжнее использовать проверенные библиотеки и готовых провайдеров.[2]

См. также

Источники

  1. NIST SP 800-63B — Digital Identity Guidelines: Authentication and Lifecycle Management
  2. OWASP — Authentication Cheat Sheet
  3. OWASP — Authorization Cheat Sheet
  4. OWASP Top 10 — A01 Broken Access Control
  5. RFC 7519 — JSON Web Token (JWT)
  6. W3C — Web Authentication (WebAuthn)
  7. OpenID Connect Core 1.0