Аутентификация и авторизация
| Аутентификация (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]
- Проверять на сервере при каждом запросе. Скрытая кнопка в интерфейсе — не защита: запрос можно отправить напрямую.
- Запрещено всё, что явно не разрешено (deny by default).
- Проверять доступ к конкретному объекту, а не только к типу операции. Классическая уязвимость IDOR: пользователь меняет в адресе
/orders/1001на/orders/1002и видит чужой заказ. - Минимальные права — и для людей, и для сервисов, и для ИИ-агентов (Принцип наименьших привилегий).
- Централизовать логику — одна библиотека или сервис политик вместо проверок, разбросанных по коду.
Нарушение контроля доступа занимает первое место в рейтинге самых распространённых уязвимостей веб-приложений OWASP Top 10.[4]
Типичные ошибки аутентификации
- Сообщения, раскрывающие, существует ли пользователь («неверный пароль» вместо «неверный логин или пароль»).
- Отсутствие ограничения попыток входа — подбор паролей.
- Токены и ключи в коде, логах и URL; их место — в хранилище секретов (Управление секретами).
- Самописная криптография и проверка JWT без проверки подписи и алгоритма. Надёжнее использовать проверенные библиотеки и готовых провайдеров.[2]
См. также
- OAuth 2.0 и OpenID Connect
- Двухфакторная аутентификация
- Хранение паролей (bcrypt, Argon2)
- Принцип наименьших привилегий
- Cookie и сессии