Как работает аутентификация в браузере
WebAuthn (Web Authentication) — это веб-стандарт, разработанный Консорциумом Всемирной паутины (W3C) и Альянсом FIDO. Он предназначен для стандартизации интерфейса и аутентификации пользователей с помощью открытого ключа на веб-основе.
Он реализует расширение обобщенного API-управления учетными данными W3C, которое является попыткой упорядочить взаимодействие между веб-сайтами и веб-браузерами при обмене учетными данными пользователя.
WebAuthn может использоваться в однофакторном режиме, при этом пользователю не нужно предоставлять какую-либо дополнительную информацию, такую как имя пользователя и пароли. Однако для дополнительной безопасности сторона, запрашивающая аутентификацию (сайт), может по-прежнему требовать эти данные, создавая схему многофакторной аутентификации.
Эта система также может быть объединена с другими факторами аутентификации, такими как жесты, биометрическая проверка или отправка кодов в приложения, что повышает общую безопасность. В это же время пользователям по-прежнему не нужно будет вводить множественные личные длинные и целые строки сложных символов.
Стандарт WebAuthn может быть реализован различными способами. Основные криптографические операции выполняются аутентификатором, который представляет собой абстрактную функциональную модель. Она, в основном, не зависит от деталей управления.
Это позволяет реализовать WebAuthn исключительно в программном обеспечении, а также использовать доверенную среду исполнения или криптографический процессор для защиты информации (TPM).
Таким образом, криптографические операции проходят с использованием внешних аппаратных носителей, через USB, Bluetooth с низким энергопотреблением или технологии беспроводной передачи данных NFC. Этот метод аутентификации, как правило, куда безопаснее. Дело в том, что материал с закрытым ключом никогда не будет доступен программному обеспечению и вредоносному ПО на компьютере. Связь с внешними аппаратными устройствами предназначена для работы с протоколом Client-Authenticator Protocol (CTAP).
WebAuthn и CTAP являются результатом проекта FIDO2, целью которого считается стандартизация безопасных и беспарольных схем аутентификации. Область применения протокола выходит за рамки браузера и интернета. В основе новой системы лежит предыдущая работа, проделанная FIDO, в частности стандарты Universal Authentication Framework (UAF) и Universal 2nd Factor (U2F).
Особенности работы
Как и его предшественник FIDO U2F, веб-аутентификация WebAuthn включает в себя 3 основных компонента. Это веб-сайт, веб-браузер и аутентификатор:
- Веб-сайт является проверяющей стороной в протоколе WebAuthn.
- Браузер — это пользователь WebAuthn.
- Аутентификатор представляет собой совокупность средств и методов, позволяющих идентифицировать аккаунт без необходимости ввода персональных данных.
Во время процесса аутентификации, WebAuthn показывает верификатору, что пользователь демонстрирует владение всеми данными, позволяющими подтвердить его личность согласно протоколу FIDO2 .
В качестве многофакторного криптографического аутентификатора могут выступать биометрические данные, включая отпечатки пальцев и сетчатку роговицы глаза. Также может использоваться ключ безопасности FIDO, который обычно представляет собой USB-накопитель.
Прокси-авторизация
Этот же механизм запроса и ответа может быть использован для прокси-авторизации. В таком случае ответ посылает промежуточный прокси-сервер, который требует авторизации. Поскольку обе формы авторизации могут использоваться одновременно, для них используются разные заголовки и коды статуса ответа. В случае с прокси, статус-код запроса 407 (Proxy Authentication Required) и заголовок Proxy-Authenticate (en-US), который содержит хотя бы один запрос, относящийся к прокси-авторизации, а для передачи авторизационных данных прокси-серверу используется заголовок Proxy-Authorization (en-US).
Доступ запрещён
Аутентификация с помощью изображений
Браузеры используют кодировку utf-8 для имени пользователя и пароля. Firefox использовал ISO-8859-1 , но она была заменена utf-8 с целью уравнения с другими браузерами, а также чтобы избежать потенциальных проблем (таких как баг 1419658).
WWW-Authenticate and Proxy-Authenticate headers
WWW-Authenticate (en-US) и Proxy-Authenticate (en-US) заголовки ответа которые определяют методы, что следует использовать для получения доступа к ресурсу. Они должны указывать, какую схему аутентификации использовать, чтобы клиент, желающий авторизоваться, знал, какие данные предоставить. Синтаксис для этих заголовков следующий:
Here, <type> is the authentication scheme ("Basic" is the most common scheme and introduced below). The realm is used to describe the protected area or to indicate the scope of protection. This could be a message like "Access to the staging site" or similar, so that the user knows to which space they are trying to get access to.
Authorization and Proxy-Authorization headers
The Authorization and Proxy-Authorization (en-US) request headers contain the credentials to authenticate a user agent with a (proxy) server. Here, the type is needed again followed by the credentials, which can be encoded or encrypted depending on which authentication scheme is used.
Authentication schemes
The most common authentication scheme is the "Basic" authentication scheme which is introduced in more details below. IANA maintains a list of authentication schemes, but there are other schemes offered by host services, such as Amazon AWS. Common authentication schemes include:
AWS4-HMAC-SHA256 (see AWS docs).
Basic authentication scheme
Security of basic authentication
Restricting access with Apache and basic authentication
To password-protect a directory on an Apache server, you will need a .htaccess and a .htpasswd file.
The .htaccess file typically looks like this:
The .htaccess file references a .htpasswd file in which each line contains of a username and a password separated by a colon (":"). You can not see the actual passwords as they are encrypted (md5 in this case). Note that you can name your .htpasswd file differently if you like, but keep in mind this file shouldn't be accessible to anyone. (Apache is usually configured to prevent access to .ht* files).
Restricting access with nginx and basic authentication
For nginx, you will need to specify a location that you are going to protect and the auth_basic directive that provides the name to the password-protected area. The auth_basic_user_file directive then points to a .htpasswd file containing the encrypted user credentials, just like in the Apache example above.
Access using credentials in the URL
Many clients also let you avoid the login prompt by using an encoded URL containing the username and the password like this:
Все знают о стандартной аутентификации пользователя в приложении. Это олдскульная процедура регистрации — пользователь вводит адрес почты, пароль и т. д., — а затем при входе мы сравниваем почту и/или пароль с сохранёнными данными. Если совпадает, даём доступ. Но времена изменились, и сегодня появилось много других методов аутентификации. Если хотите оставаться востребованным программистом/разработчиком в этом меняющемся, словно калейдоскоп, мире разработки ПО, то вы должны знать обо всех этих новых методах.
Нельзя отрицать, что в любых приложениях и ОС «аутентификация» — крайне важный элемент обеспечения сохранности пользовательских данных и регулирования доступа к информации. Чтобы понять, какой метод аутентификации для вас лучше, нужно разбираться в достоинствах и недостатках всех методов, а также неплохо представлять, как же они работают.
Здесь я постараюсь рассказать о большинстве распространённых сегодня методов аутентификации. Это не подробное техническое руководство, а лишь способ познакомить вас с ними. Хотя методы описаны с учётом применения в вебе, эти идеи можно реализовать и в других условиях.
Аутентификация на основе сессий
Чтобы избавиться от этого неудобства, придумали аутентификацию на основе сессий/кук, с помощью которых реализовали отслеживание состояний (stateful). Это означает, что аутентификационная запись или сессия должны храниться и на сервере, и на клиенте. Сервер должен отслеживать активные сессии в базе данных или памяти, а на фронтенде создаётся кука, в которой хранится идентификатор сессии. Это аутентификация на основе куки, самая распространённый и широко известный метод, используемый уже давно.
Процедура аутентификации на основе сессий:
- Пользователь вводит в браузере своё имя и пароль, после чего клиентское приложение отправляет на сервер запрос.
- Сервер проверяет пользователя, аутентифицирует его, шлёт приложению уникальный пользовательский токен (сохранив его в памяти или базе данных).
- Клиентское приложение сохраняет токены в куках и отправляет их при каждом последующем запросе.
- Сервер получает каждый запрос, требующий аутентификации, с помощью токена аутентифицирует пользователя и возвращает запрошенные данные клиентскому приложению.
- Когда пользователь выходит, клиентское приложение удаляет его токен, поэтому все последующие запросы от этого клиента становятся неаутентифицированными.
У этого метода несколько недостатков.
- При каждой аутентификации пользователя сервер должен создавать у себя запись. Обычно она хранится в памяти, и при большом количестве пользователей есть вероятность слишком высокой нагрузки на сервер.
- Поскольку сессии хранятся в памяти, масштабировать не так просто. Если вы многократно реплицируете сервер, то на все новые серверы придётся реплицировать и все пользовательские сессии. Это усложняет масштабирование. (Я считал, этого можно избежать, если иметь выделенный сервер для управления сессиями, но это сложно реализовать, да и не всегда возможно.)
Аутентификация на основе токенов
Аутентификация на основе токенов в последние годы стала очень популярна из-за распространения одностраничных приложений, веб-API и интернета вещей. Чаще всего в качестве токенов используются Json Web Tokens (JWT) . Хотя реализации бывают разные, но токены JWT превратились в стандарт де-факто.
При аутентификации на основе токенов состояния не отслеживаются . Мы не будем хранить информацию о пользователе на сервере или в сессии и даже не будем хранить JWT, использованные для клиентов.
Процедура аутентификации на основе токенов:
- Пользователь вводит имя и пароль.
- Сервер проверяет их и возвращает токен (JWT), который может содержать метаданные вроде user_id, разрешений и т. д.
- Токен хранится на клиентской стороне, чаще всего в локальном хранилище, но может лежать и в хранилище сессий или кук.
- Последующие запросы к серверу обычно содержат этот токен в качестве дополнительного заголовка авторизации в виде Bearer . Ещё токен может пересылаться в теле POST-запроса и даже как параметр запроса.
- Сервер расшифровывает JWT, если токен верный, сервер обрабатывает запрос.
- Когда пользователь выходит из системы, токен на клиентской стороне уничтожается, с сервером взаимодействовать не нужно.
У метода есть ряд преимуществ:
- Главное преимущество: поскольку метод никак не оперирует состояниями, серверу не нужно хранить записи с пользовательскими токенами или сессиями. Каждый токен самодостаточен, содержит все необходимые для проверки данные, а также передаёт затребованную пользовательскую информацию. Поэтому токены не усложняют масштабирование.
- В куках вы просто храните ID пользовательских сессий, а JWT позволяет хранить метаданные любого типа, если это корректный JSON.
- При использовании кук бэкенд должен выполнять поиск по традиционной SQL-базе или NoSQL-альтернативе, и обмен данными наверняка длится дольше, чем расшифровка токена. Кроме того, раз вы можете хранить внутри JWT дополнительные данные вроде пользовательских разрешений, то можете сэкономить и дополнительные обращения поисковые запросы на получение и обработку данных.
Допустим, у вас есть API-ресурс /api/orders, который возвращает последние созданные приложением заказы, но просматривать их могут только пользователи категории админов. Если вы используете куки, то, сделав запрос, вы генерируете одно обращение к базе данных для проверки сессии, ещё одно обращение — для получения пользовательских данных и проверки, относится ли пользователь к админам, и третье обращение — для получения данных.
А если вы применяете JWT, то можете хранить пользовательскую категорию уже в токене. Когда сервер запросит его и расшифрует, вы можете сделать одно обращение к базе данных, чтобы получить нужные заказы. - У использования кук на мобильных платформах есть много ограничений и особенностей. А токены сильно проще реализовать на iOS и Android. К тому же токены проще реализовать для приложений и сервисов интернета вещей, в которых не предусмотрено хранение кук.
Благодаря всему этому аутентификация на основе токенов сегодня набирает популярность.
Беспарольная аутентификация
Первой реакцией на термин «беспарольная аутентификация» может быть «Как аутентифицировать кого-то без пароля? Разве такое возможно?»
В наши головы внедрено убеждение, что пароли — абсолютный источник защиты наших аккаунтов. Но если изучить вопрос глубже, то выяснится, что беспарольная аутентификация может быть не просто безопасной, но и безопаснее традиционного входа по имени и паролю. Возможно, вы даже слышали мнение, что пароли устарели.
Беспарольная аутентификация — это способ конфигурирования процедуры входа и аутентификации пользователей без ввода паролей. Идея такая:
Вместо ввода почты/имени и пароля пользователи вводят только свою почту. Ваше приложение отправляет на этот адрес одноразовую ссылку, пользователь по ней кликает и автоматически входит на ваш сайт / в приложение. При беспарольной аутентификации приложение считает, что в ваш ящик пришло письмо со ссылкой, если вы написали свой, а не чужой адрес.
Есть похожий метод, при котором вместо одноразовой ссылки по SMS отправляется код или одноразовый пароль. Но тогда придётся объединить ваше приложение с SMS-сервисом вроде twilio (и сервис не бесплатен). Код или одноразовый пароль тоже можно отправлять по почте.
И ещё один, менее (пока) популярный (и доступный только на устройствах Apple) метод беспарольной аутентификации: использовать Touch ID для аутентификации по отпечаткам пальцев. Подробнее о технологии .
Если вы пользуетесь Slack , то уже могли столкнуться с беспарольной аутентификацией.
Medium предоставляет доступ к своему сайту только по почте . Я недавно обнаружил, что Auth0 , или Facebook AccountKit , — это отличный вариант для реализации беспарольной системы для вашего приложения.
Что может пойти не так?
Если кто-то получит доступ к пользовательским почтам, он получит и доступ к приложениям и сайтам. Но это не ваша головная боль — беспокоиться о безопасности почтовых аккаунтов пользователей. Кроме того, если кто-то получит доступ к чужой почте, то сможет перехватить аккаунты в приложениях с беспарольной аутентификацией, воспользовавшись функцией восстановления пароля. Но мы ничего не можем поделать с почтой наших пользователей. Пойдём дальше.
В чём преимущества?
Как часто вы пользуетесь ссылкой «забыли пароль» для сброса чёртового пароля, который так и не смогли вспомнить после нескольких неудачных попыток входа на сайт / в приложение? Все мы бываем в такой ситуации. Все пароли не упомнишь, особенно если вы заботитесь о безопасности и для каждого сайта делаете отдельный пароль (соблюдая все эти «должен состоять не менее чем из восьми символов, содержать хотя бы одну цифру, строчную букву и специальный символ»). От всего этого вас избавит беспарольная аутентификация. Знаю, вы думаете сейчас: «Я использую менеджер паролей, идиот». Уважаю. Но не забывайте, что подавляющее большинство пользователей не такие техногики, как вы. Это нужно учитывать.
Беспарольная аутентификация хороша не только для пользователей, но и для вас как разработчика. Вам не нужно реализовывать механизм восстановления паролей. Все в выигрыше.
Если вы думаете, что какие-то пользователи предпочтут старомодные логин/пароль, то предоставьте им оба варианта, чтобы они могли выбирать.
Сегодня беспарольная аутентификация быстро набирает популярность.
Единая точка входа (Single Sign On, SSO)
Обращали внимание, что, когда логинишься в браузере в каком-нибудь Google-сервисе, например Gmail, а потом идёшь на Youtube или иной Google-сервис, там не приходится логиниться? Ты автомагически получаешь доступ ко всем сервисам компании. Впечатляет, верно? Ведь хотя Gmail и Youtube — это сервисы Google, но всё же раздельные продукты. Как они аутентифицируют пользователя во всех продуктах после единственного входа?
Этот метод называется единой точкой входа (Single Sign On, SSO).
Реализовать его можно по-разному. Например, использовать центральный сервис для оркестрации единого входа между несколькими клиентами. В случае с Google этот сервис называется Google Accounts . Когда пользователь логинится, Google Accounts создаёт куку, которая сохраняется за пользователем, когда тот ходит по принадлежащим компании сервисам. Как это работает:
- Пользователь входит в один из сервисов Google.
- Пользователь получает сгенерированную в Google Accounts куку.
- Пользователь идёт в другой продукт Google.
- Пользователь снова перенаправляется в Google Accounts.
- Google Accounts видит, что пользователю уже присвоена кука, и перенаправляет пользователя в запрошенный продукт.
Очень простое описание единой точки входа: пользователь входит один раз и получает доступ ко всем системам без необходимости входить в каждую из них. В этой процедуре используется три сущности, доверяющие другу прямо и косвенно. Пользователь вводит пароль (или аутентифицируется иначе) у поставщика идентификационной информации (identity provider, IDP), чтобы получить доступ к поставщику услуги (service provider (SP). Пользователь доверяет IDP, и SP доверяет IDP, так что SP может доверять пользователю.
Выглядит очень просто, но конкретные реализации бывают очень сложными. Подробнее об этом методе аутентификации .
Аутентификация в соцсетях
Уверен, эта картинка знакома всем:
Это часто называют аутентификацией в соцсетях (Social sign-in) или социальным логином (Social Login). Вы можете аутентифицировать пользователей по их аккаунтам в соцсетях. Тогда пользователям не придётся регистрироваться отдельно в вашем приложении.
Формально социальный логин — это не отдельный метод аутентификации. Это разновидность единой точки входа с упрощением процесса регистрации/входа пользователя в ваше приложение.
Лучшее из двух миров
Пользователи могут войти в ваше приложение одним кликом, если у них есть аккаунт в одной из соцсетей. Им не нужно помнить логины и пароли. Это сильно улучшает опыт использования вашего приложения. Вам как разработчику не нужно волноваться о безопасности пользовательских данных и думать о проверке адресов почты — они уже проверены соцсетями. Кроме того, в соцсетях уже есть механизмы восстановления пароля.
Как использовать
Как разработчик вы должны разбираться в работе этого метода аутентификации. Большинство соцсетей в качестве механизма аутентификации используют авторизацию через OAuth2 (некоторые используют OAuth1, например Twitter). Разберёмся, что такое OAuth. Соцсеть — это сервер ресурсов , ваше приложение — клиент , а пытающийся войти в ваше приложение пользователь — владелец ресурса . Ресурсом называется пользовательский профиль / информация для аутентификации. Когда пользователь хочет войти в ваше приложение, оно перенаправляет пользователя в соцсеть для аутентификации (обычно это всплывающее окно с URL’ом соцсети). После успешной аутентификации пользователь должен дать вашему приложению разрешение на доступ к своему профилю из соцсети. Затем соцсеть возвращает пользователя обратно в ваше приложение, но уже с токеном доступа. В следующий раз приложение возьмёт этот токен и запросит у соцсети информацию из пользовательского профиля. Так работает OAuth (ради простоты я опустил технические подробности).
Для реализации такого механизма вам может понадобиться зарегистрировать своё приложение в разных соцсетях. Вам дадут app_id и другие ключи для конфигурирования подключения к соцсетям. Также есть несколько популярных библиотек/пакетов (вроде Passport , Laravel Socialite и т. д.), которые помогут упростить процедуру и избавят от излишней возни.
Двухфакторная аутентификация (2FA)
Двухфакторная аутентификация (2FA) улучшает безопасность доступа за счёт использования двух методов (также называемых факторами) проверки личности пользователя. Это разновидность многофакторной аутентификации . Наверное, вам не приходило в голову, но в банкоматах вы проходите двухфакторную аутентификацию: на вашей банковской карте должна быть записана правильная информация, и в дополнение к этому вы вводите PIN. Если кто-то украдёт вашу карту, то без кода он не сможет ею воспользоваться. (Не факт! — Примеч. пер.) То есть в системе двухфакторной аутентификации пользователь получает доступ только после того, как предоставит несколько отдельных частей информации.
Требования к установке лаборатории:
- Сервер Apache (Ubuntu 14.04)
- Машина для пентестинга (Kali Linux)
Настройка аутентификации по вводу пароля
Установка пакета утилит Apache
sudo apt-get install apache2 apache2-utils
Создание файла паролей
Теперь необходимо ввести команду htpasswd для создания файла паролей, который Apache будет использовать для аутентификации пользователей. Применение скрытого файла “htpasswd ” в каталоге конфигурации /etc/apache2 поможет хранить конфиденциальные данные юзеров в безопасности.
sudo htpasswd -c /etc/apache2/.htpasswd raj
cat /etc/apache2/.htpasswd
Настройка контроля доступа внутри виртуального хоста
Пользователь сохранит следующую конфигурацию в виде 000-default.conf файла.
<Directory "/var/www/html">
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
Настройка контроля доступа с помощью файлов .htaccess
Человеку следует открыть основной конфигурационный файл Apache, чтобы включить защиту паролем с помощью файлов .htaccess и добавить следующую выделенную строку, которую можно увидеть ниже.
sudo gedit /etc/apache2/apache2.conf
ServerName localhost
После этого пользователь включит обработку .htaccess путем изменения директивы AllowOverride “None” на “All” в блоке для каталога /var/www, а затем сохранит файл и перезапустит службу Аpache.
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Затем ему нужно будет добавить файл htaccess в каталог, который он хочет защитить. Здесь, к примеру, пользователь желает ввести ограничение на весь веб-сайт, что может быть сделано через /var / www / html. Однако человек также имеет возможность поместить этот файл в любой другой каталог, где он хочет ограничить доступ для иных юзеров:
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
sudo service apache2 restart
Во время настройки файла .htaccess пользователь добавил несколько опций в отношении каталога блоков. Стоит посмотреть, что несет в себе эта новая конфигурация:
- AuthType Basic: позволит настроить базовую аутентификацию для сайта пользователя.
- AuthName “Restricted Contents” : покажет имя аутентификации в приглашении.
- AuthUserFile /etc/apache2/.htpasswd : сможет показать расположение файла аутентификации.
- Require Valid-user : будет использоваться одним пользователем, который подтвердил свою аутентификацию и которому разрешен доступ к веб-сайту.
Подтверждение проверки паролем
Пользователь попробует получить доступ к ограниченному контенту в веб-браузере, чтобы убедиться, что его контент защищен. Эта опция будет доступна после запроса имени пользователя и пароля, что выглядит следующим образом:
Если кто-то попытается получить доступ к веб-сайту без аутентификации или не пройдет необходимую страницу аутентификации, то ему будет показана 401 ошибка несанкционированного доступа .
Как можно увидеть на картинке, теперь пользователь может получить доступ к содержимому веб-сайта.
Читайте также: