В этой статье мы поговорим о системе безопасного выполнения аутентификации и авторизации. Для начала давайте разберемся, в чем разница между аутентификацией и авторизацией. — это процесс подтверждения того, что вы являетесь тем, кем вы себя называете, при доступе к приложению. Аутентификация — это процесс определения и применения политик доступа, то есть того, что вы можете делать после аутентификации. Авторизация В этой статье мы увидим: Почему аутентификация и авторизация важны Как работает аутентификация Как работает авторизация Проектирование системы аутентификации Заключение Почему аутентификация и авторизация важны? Допустим, мы находимся на совещании, и вы ведете разговор. Чтобы запросить обновления/статус чего-либо у нужного человека, вам необходимо идентифицировать (т. е. ) этого человека. Даже для того, чтобы поделиться с человеком некоторыми конфиденциальными данными, вам необходимо правильно аутентифицировать его. И здесь на помощь приходит аутентификация. аутентифицировать Теперь скажем, на том же заседании необходимо принять несколько решений. Поэтому звонки должны принимать люди, имеющие право принимать эти решения, мы не можем просто позволить всем делать все. Очевидно, что некоторые люди недостаточно подготовлены, чтобы принимать какие-то решения, а некоторые наверняка попытаются извлечь из этого максимум пользы. Это приводит к , которая дает определенным людям права на определенные действия. авторизации Как работает аутентификация? Чтобы аутентифицировать человека, мы можем назначить каждому человеку уникальную фразу, при условии, что человек правильно произнес эту фразу и свое имя. Можно сказать, что ок, мы идентифицировали человека. Это обычный подход к именам пользователей и паролям. Когда указаны правильные учетные данные, система считает удостоверение действительным и предоставляет доступ. Это известно как 1FA или (SFA). однофакторная аутентификация SFA считается довольно небезопасным. Почему? Потому что пользователи, как известно, плохо защищают свою информацию для входа. Многофакторная аутентификация (MFA) — это более безопасная альтернатива, которая требует от пользователей подтверждения своей личности несколькими способами. Вот некоторые из таких способов: Одноразовые PIN-коды/OTP Приложения для аутентификации, запускаемые безопасными сторонними организациями (например, Google/Microsoft Authenticator) Биометрия После аутентификации человек будет продолжать свободно выполнять действия в приложении. Ожидается, что приложение будет узнавать человека на протяжении всего пути, не забывая его. В идеале было бы слишком много просить пользователя предоставлять пароль каждый раз, когда он переходит на другую страницу или выполняет какую-либо деятельность. Поэтому нам нужен способ поддерживать аутентификацию пользователя после того, как он ввел свои учетные данные и прошел однократную аутентификацию. Это называется . управлением сеансами Два способа сохранить аутентификацию пользователя: : когда пользователь входит на веб-сайт в браузере, сервер создает сеанс для этого пользователя и назначает идентификатор сеанса. Этот идентификатор сеанса сохраняется на сервере для справки и отправляется обратно пользователю для сохранения в файле cookie в браузере. Теперь каждый раз, когда пользователь делает запрос, браузер отправляет идентификатор сеанса вместе с запросом. Это поможет в аутентификации запроса. И, таким образом, сохраняя аутентификацию во время нахождения пользователя на сайте. Аутентификация на основе сеанса : для этого сервер создает зашифрованный токен, который отправляется пользователю и сохраняется только браузером как файлы cookie HttpOnly. Вся необходимая информация, такая как информация пользователя, разрешения и срок действия токена, зашифрована внутри токена. Токен отправляется вместе с вызовами на сервер. Сервер просто расшифровывает токен с помощью секретного ключа и проверяет пользователя. Этот токен обновляется через определенные промежутки времени. Аутентификация на основе токенов Основные различия между этими двумя подходами заключаются в том, что аутентификация на основе токенов , поскольку токен не нужно хранить на стороне сервера. Но для аутентификации на основе сеанса токен также необходимо хранить на стороне сервера, что делает его . Что вызывает сложности при масштабировании системы или росте количества пользователей. не имеет состояния сохраняющим состояние Для аутентификации на основе токенов мы в основном используем JWT (веб-токены JSON). Как работает авторизация? После аутентификации пользователя нам все равно нужно будет гарантировать, что ему разрешен доступ только к ресурсам, на доступ к которым у него есть разрешения. Несанкционированный доступ к конфиденциальным данным может обернуться катастрофой. По принципу наименьших привилегий компании обычно устанавливают политику доступа таким образом, чтобы по умолчанию у вас был доступ к тому, что вам абсолютно необходимо. И затем по ходу дела у вас появится дополнительный доступ. Распространенные способы сегментирования доступа: : пользователи назначаются определенной группе/роли с заданными разрешениями. Примеры: администратор, участник, владелец. Управление доступом на основе ролей (RBAC) : динамически определяет права доступа во время авторизации на основе политик и правил. Политики основаны на ролях пользователей, должностных функциях и организационных требованиях. Управление доступом на основе политик (PBAC) . Пользователям разрешен доступ в соответствии с такими атрибутами, как должность, сертификация, обучение и/или факторами окружающей среды, такими как местоположение. Управление доступом на основе атрибутов (ABAC) : каждый пользователь или организация имеет индивидуальные разрешения, которые можно включать или отключать, аналогично установке нового приложения на телефон и решению, какие разрешения предоставить (службы определения местоположения, контакты и т. д.). Списки контроля доступа (ACL) ACL часто используется на более детальном уровне, чем ABAC или RBAC, например, чтобы предоставить отдельным пользователям доступ к определенному файлу. ABAC и RBAC обычно устанавливаются в рамках политики всей компании. Проектирование системы аутентификации Требования Давайте сначала начнем с определения системы: функциональных требований : Разрешить пользователям регистрироваться, предоставив необходимую информацию. Регистрация : Аутентификация пользователей на основе их учетных данных. Вход : эффективно управляйте сеансами пользователей для обеспечения безопасности. Управление сеансами : Обеспечьте пользователям безопасный процесс восстановления своих паролей. Восстановление пароля : определение ролей и разрешений для разных типов пользователей. Контроль доступа : ведение подробных журналов событий аутентификации для аудита. Журнал аудита : обеспечьте низкую задержку и быстрое время отклика. Производительность Вот несколько , которые мы не будем рассматривать в рамках этой статьи: нефункциональных требований . Внедрите надежную систему MFA. Многофакторная аутентификация (MFA) . Уделяйте приоритетное внимание безопасности данных посредством шифрования, безопасного хранения и безопасной связи. Безопасность : спроектируйте систему для обработки растущего числа пользователей и транзакций. Масштабируемость : минимизируйте время простоя системы и обеспечьте высокую доступность. Надежность : Разработайте интуитивно понятный пользовательский интерфейс для удобной работы. Удобство использования Оценка мощности Оценка трафика Сначала давайте начнем с . Предполагая, что средний трафик составляет 100 000 в месяц. Мы оцениваем трафик в 100 тысяч пользователей в месяц. Что соответствует 0,04 запроса в секунду. В 90% случаев нам нужно будет отвечать на каждый запрос в течение 500 мс, т. е. нам требуется задержка p90 500 мс. оценки трафика assumed_traffic_per_month = 100000 #requests assumed_traffic_per_day = assumed_traffic_per_month / 30 ~= 3350 (assuming on higher end; 3333.33 to be precise) estimated_time_per_request = 500 #ms; P90 of 500ms traffic_per_second = (assumed_traffic_per_month) / (30*24*60*60) = 0.04 : 500 мс (максимально приемлемая задержка, независящая от нагрузки на систему). Средняя мощность, которую может занять 1 экземпляр, по нашим расчетам, составляет примерно 35 мс для обслуживания запроса, при условии, что для обработки запроса не происходит тяжелой обработки. конкретный запрос. Целевой уровень обслуживания (SLO) Давайте сгенерируем еще две используя приведенные выше метрики. производные метрики, : Допустимое отставание на экземпляр: Максимальное количество запросов (нагрузки), которое может быть принято экземпляром без ущерба для SLO. Емкость : отставание на экземпляр: общее количество запросов (нагрузки), поступающих в единицу/экземпляр, на основе текущего трафика. Спрос Таким образом, SLO = 500ms approx_response_time_for_one_request = 35 #ms capacity = SLO/approx_response_time_for_one_request = 500 / 35 ~= 20 load_on_one_instance = 0.04 instances_available = 1 demand = traffic_per_second / instances_available = 0.04 Учитывая спрос и доступную мощность, давайте рассчитаем общее количество необходимых экземпляров. total_units_required = demand / capacity = 0.04 / 20 = 0.002 ~= 1 Таким образом, мы легко сможем обрабатывать 100 тысяч запросов в месяц, со скоростью 0,04 запроса в секунду, с 1 экземпляром. Где каждое устройство может обрабатывать 20 запросов в секунду без ущерба для SLO. Оценка хранилища В идеале нам нужно было бы хранить данные пользователя для каждого пользователя для аутентификации и авторизации доступа. Предположим, 5 КБ на пользователя. monthly_new_users = 500 monthly_additional_storage = 500 * 5kb = 2500kb ~= 2GB Таким образом, каждый месяц, если мы будем подключать 500 новых пользователей, нам потребуется на 2 ГБ больше места для хранения данных. В случае, если мы хотим вести журналы аутентификации. Ожидается, что для хранения каждого запроса аутентификации потребуется 2 КБ. auth_request_size = 2kb #assumption monthly_storage = monthly_visitors * auth_request_size = 100,000 * 2KB ~= 200MB Таким образом, каждый месяц нам потребуется дополнительно 200 МБ при условии ежемесячного трафика в 100 тысяч. Проектирование базы данных Теперь, когда мы сделали оценку мощности. Давайте создадим схемы базы данных, необходимые для поддержки функциональных требований. Давайте быстро пробежимся по таблицам. Мы используем 6 таблиц. Пользователи — для хранения всей информации о пользователях. Учетные данные — для хранения учетных данных доступа/обновления после авторизации пользователя. Пароли — для хранения зашифрованных паролей пользователей. PasswordRequests — для хранения запросов на смену пароля, поступающих для конкретного пользователя. Сеансы — для хранения информации о том, когда у пользователя был активный сеанс и когда была его последняя активность. ActivityApproval — для хранения запросов на одобрение действий, выполняемых конкретным пользователем, которые будут проверены администратором. Высокоуровневый дизайн системы аутентификации Конечные точки системы Конечная точка Описание /авторизоваться Аутентификация учетных данных пользователя. /выйти Завершить сеанс пользователя и отозвать токены аутентификации. /регистр Создайте нового пользователя. /обновление/:идентификатор пользователя Обновите информацию о пользователе. /удалить/:идентификатор пользователя Удалить учетную запись пользователя. /grant/:userId/:разрешение Предоставьте пользователю определенные разрешения. /revoke/:userId/:разрешение Отозвать разрешения у пользователя. /check/:userId/:ресурс Проверьте доступ пользователя к определенному ресурсу. /создать/:идентификатор пользователя Создайте новый сеанс пользователя. /expire/:ИДсессиона Завершить сеанс пользователя. /validate/:ИДсессиона Подтвердите активный сеанс пользователя. Выполнение требований Теперь, когда все готово, давайте посмотрим, как мы можем выполнить все требования. Постановка на учет – Когда новый пользователь посещает наше приложение. Нам необходимо хранить данные пользователя, чтобы мы могли авторизовать/идентифицировать пользователя при следующем посещении. Требование — когда новый пользователь посещает приложение и вводит данные пользователя, а также адрес электронной почты и пароль. Это будет зафиксировано в базе данных. Данные пользователя будут храниться в таблице User. А пароль будет храниться в таблице учетных данных в зашифрованном виде. Выполнено Авторизоваться — когда существующий пользователь посещает наше приложение. Нам необходимо идентифицировать пользователя, чтобы мы могли авторизовать/идентифицировать его действия и показать им данные, которые им принадлежат. Требование — когда существующий пользователь посещает приложение и вводит свои данные, адрес электронной почты и пароль. Мы хешируем пароль и сопоставляем его с хешем, хранящимся для пользователя в таблице учетных данных. Если он соответствует, то мы смогли успешно идентифицировать пользователя. В противном случае им необходимо ввести правильный пароль, который они ввели при регистрации. Этот процесс называется . Выполнено Аутентификация Управление сеансами — когда пользователь прошел аутентификацию, введя своего пользователя и пароль. Нам необходимо убедиться, что они остаются в системе, когда выполняют свои будущие действия или пытаются просмотреть конфиденциальные данные, не заставляя их снова и снова вводить свой пароль. Требование — когда пользователь успешно проходит аутентификацию. Сервер аутентификации будет делиться с клиентом двумя токенами. . Access_token может содержать зашифрованные данные и имеет короткий срок действия по соображениям безопасности. Как только клиент получает access_token, он отправляет его обратно вместе с каждым запросом, что помогает аутентифицировать запрос. По истечении срока действия access_token клиент должен запросить новый access_token, используя предоставленныйrefresh_token. Это помогает поддерживать сеанс. Выполнено access_token иrefresh_token Восстановление пароля . Если пользователь забывает свой пароль, ему необходимо иметь возможность безопасно сбросить пароль. Требование — когда пользователь забывает свой пароль, он может указать свой адрес электронной почты на странице забытого пароля, и мы сгенерируем одноразовый код и отправим ссылку на его электронную почту. Когда пользователь нажимает на эту ссылку с кодом и адресом электронной почты. Мы сможем надежно определить, что запрос на восстановление пароля является подлинным. И предоставьте пользователю возможность установить новый пароль. И таким образом иметь возможность восстановить пароль. Выполнено Контроль доступа . Когда пользователь выполняет определенное действие, нам необходимо убедиться, что пользователь прошел аутентификацию для выполнения этого действия, и только после этого разрешить выполнение этого действия. Требование . Для простоты мы будем сохранять список действий, скажем, от 1 до 12. Для каждого пользователя мы будем поддерживать аутентифицированные действия для этого пользователя. Итак, теперь предположим, что пользователь пытается выполнить действие #id 4. Мы проверим, есть ли у пользователя разрешения на выполнение действия 4. Если да, мы продолжим и выполним запрос. В противном случае мы показываем, что запрос не выполнен из-за отсутствия разрешений. Выполнено Аудиторский след . В случае инцидента безопасности у нас должно быть достаточно журналов для просмотра и правдоподобная причина того, что могло произойти, или любые указания на то, что могло быть возможной причиной этого. Требование — для таких сценариев мы можем вести журналы для каждого действия аутентификации, происходящего на сервере. (а). Для каждого запроса на вход в систему мы будем вести журнал, в котором будет указано, когда произошла аутентификация, откуда, IP-адреса и другие соответствующие данные. (б). Для каждого запроса на восстановление пароля мы будем вести журнал с указанием того, когда он был инициирован, откуда, IP-адреса, был ли запрос завершен и другие соответствующие сведения. (с). Кроме того, мы будем вести журналы каждый раз, когда пользователь авторизуется/не авторизуется на какое-либо действие и кем. В целом эти журналы должны указывать на то, что могло произойти при попытке понять какой-либо сценарий. Выполнено Производительность . Требования к производительности, как описано в разделе оценки емкости, составляют 0,04 запроса в секунду и 100 тысяч запросов в месяц. Требование . Мы уже выполнили требование с достаточным количеством серверов в разделе оценки мощности. Выполнено Заключение В этой статье мы начали с понимания разницы между аутентификацией и авторизацией. Далее мы создали систему аутентификации и авторизации. Это безопасно, надежно, обеспечивает производительность, соответствует отраслевым стандартам и отвечает всем желаемым требованиям. В дальнейшем я мог бы обновить некоторые части статьи, чтобы она оставалась актуальной, а также чтобы охватить больше информации и идей по созданию такой системы.