paint-brush
Проектирование функциональных систем аутентификации и авторизациик@iarunava
3,226 чтения
3,226 чтения

Проектирование функциональных систем аутентификации и авторизации

к Arunava12m2024/05/05
Read on Terminal Reader

Слишком долго; Читать

В этой статье мы поговорим о системе безопасного выполнения аутентификации и авторизации.
featured image - Проектирование функциональных систем аутентификации и авторизации
Arunava HackerNoon profile picture
0-item

В этой статье мы поговорим о системе безопасного выполнения аутентификации и авторизации. Для начала давайте разберемся, в чем разница между аутентификацией и авторизацией.


  • Аутентификация — это процесс подтверждения того, что вы являетесь тем, кем вы себя называете, при доступе к приложению.
  • Авторизация — это процесс определения и применения политик доступа, то есть того, что вы можете делать после аутентификации.

В этой статье мы увидим:



Почему аутентификация и авторизация важны?

Аутентификация и авторизация (источник: Джеффри Марвин Форонс | Geek Culture. Изменено)


Допустим, мы находимся на совещании, и вы ведете разговор. Чтобы запросить обновления/статус чего-либо у нужного человека, вам необходимо идентифицировать (т. е. аутентифицировать ) этого человека. Даже для того, чтобы поделиться с человеком некоторыми конфиденциальными данными, вам необходимо правильно аутентифицировать его. И здесь на помощь приходит аутентификация.


Теперь скажем, на том же заседании необходимо принять несколько решений. Поэтому звонки должны принимать люди, имеющие право принимать эти решения, мы не можем просто позволить всем делать все. Очевидно, что некоторые люди недостаточно подготовлены, чтобы принимать какие-то решения, а некоторые наверняка попытаются извлечь из этого максимум пользы. Это приводит к авторизации , которая дает определенным людям права на определенные действия.

Как работает аутентификация?

аутентификация на основе токенов; Токен доступа и токен обновления [SPA=SinglePageApplication, RT=RefreshToken, AT=AccessToken, RS=RefreshServer, AS=AuthorizationServer] (Источник: Okta)


Чтобы аутентифицировать человека, мы можем назначить каждому человеку уникальную фразу, при условии, что человек правильно произнес эту фразу и свое имя. Можно сказать, что ок, мы идентифицировали человека. Это обычный подход к именам пользователей и паролям. Когда указаны правильные учетные данные, система считает удостоверение действительным и предоставляет доступ. Это известно как 1FA или однофакторная аутентификация (SFA).


SFA считается довольно небезопасным. Почему? Потому что пользователи, как известно, плохо защищают свою информацию для входа. Многофакторная аутентификация (MFA) — это более безопасная альтернатива, которая требует от пользователей подтверждения своей личности несколькими способами. Вот некоторые из таких способов:


  • Одноразовые PIN-коды/OTP
  • Приложения для аутентификации, запускаемые безопасными сторонними организациями (например, Google/Microsoft Authenticator)
  • Биометрия


После аутентификации человек будет продолжать свободно выполнять действия в приложении. Ожидается, что приложение будет узнавать человека на протяжении всего пути, не забывая его. В идеале было бы слишком много просить пользователя предоставлять пароль каждый раз, когда он переходит на другую страницу или выполняет какую-либо деятельность. Поэтому нам нужен способ поддерживать аутентификацию пользователя после того, как он ввел свои учетные данные и прошел однократную аутентификацию. Это называется управлением сеансами .


Два способа сохранить аутентификацию пользователя:

  • Аутентификация на основе сеанса : когда пользователь входит на веб-сайт в браузере, сервер создает сеанс для этого пользователя и назначает идентификатор сеанса. Этот идентификатор сеанса сохраняется на сервере для справки и отправляется обратно пользователю для сохранения в файле cookie в браузере. Теперь каждый раз, когда пользователь делает запрос, браузер отправляет идентификатор сеанса вместе с запросом. Это поможет в аутентификации запроса. И, таким образом, сохраняя аутентификацию во время нахождения пользователя на сайте.
  • Аутентификация на основе токенов : для этого сервер создает зашифрованный токен, который отправляется пользователю и сохраняется только браузером как файлы cookie HttpOnly. Вся необходимая информация, такая как информация пользователя, разрешения и срок действия токена, зашифрована внутри токена. Токен отправляется вместе с вызовами на сервер. Сервер просто расшифровывает токен с помощью секретного ключа и проверяет пользователя. Этот токен обновляется через определенные промежутки времени.


Основные различия между этими двумя подходами заключаются в том, что аутентификация на основе токенов не имеет состояния , поскольку токен не нужно хранить на стороне сервера. Но для аутентификации на основе сеанса токен также необходимо хранить на стороне сервера, что делает его сохраняющим состояние . Что вызывает сложности при масштабировании системы или росте количества пользователей.


Для аутентификации на основе токенов мы в основном используем JWT (веб-токены JSON).

Как работает авторизация?

Ролевой контроль авторизации (RBAC) (источник: Аджай Шехават | Dribble)

После аутентификации пользователя нам все равно нужно будет гарантировать, что ему разрешен доступ только к ресурсам, на доступ к которым у него есть разрешения. Несанкционированный доступ к конфиденциальным данным может обернуться катастрофой. По принципу наименьших привилегий компании обычно устанавливают политику доступа таким образом, чтобы по умолчанию у вас был доступ к тому, что вам абсолютно необходимо. И затем по ходу дела у вас появится дополнительный доступ. Распространенные способы сегментирования доступа:


  • Управление доступом на основе ролей (RBAC) : пользователи назначаются определенной группе/роли с заданными разрешениями. Примеры: администратор, участник, владелец.
  • Управление доступом на основе политик (PBAC) : динамически определяет права доступа во время авторизации на основе политик и правил. Политики основаны на ролях пользователей, должностных функциях и организационных требованиях.
  • Управление доступом на основе атрибутов (ABAC) . Пользователям разрешен доступ в соответствии с такими атрибутами, как должность, сертификация, обучение и/или факторами окружающей среды, такими как местоположение.
  • Списки контроля доступа (ACL) : каждый пользователь или организация имеет индивидуальные разрешения, которые можно включать или отключать, аналогично установке нового приложения на телефон и решению, какие разрешения предоставить (службы определения местоположения, контакты и т. д.).


Экран списков контроля доступа (источник: Povio)


ACL часто используется на более детальном уровне, чем ABAC или RBAC, например, чтобы предоставить отдельным пользователям доступ к определенному файлу. ABAC и RBAC обычно устанавливаются в рамках политики всей компании.


Проектирование системы аутентификации

Проектирование системы аутентификации и авторизации (источник: InterviewPen. Modified)

Требования

Давайте сначала начнем с определения функциональных требований системы:

  • Регистрация : Разрешить пользователям регистрироваться, предоставив необходимую информацию.
  • Вход : Аутентификация пользователей на основе их учетных данных.
  • Управление сеансами : эффективно управляйте сеансами пользователей для обеспечения безопасности.
  • Восстановление пароля : Обеспечьте пользователям безопасный процесс восстановления своих паролей.
  • Контроль доступа : определение ролей и разрешений для разных типов пользователей.
  • Журнал аудита : ведение подробных журналов событий аутентификации для аудита.
  • Производительность : обеспечьте низкую задержку и быстрое время отклика.


Вот несколько нефункциональных требований , которые мы не будем рассматривать в рамках этой статьи:

  • Многофакторная аутентификация (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


Целевой уровень обслуживания (SLO) : 500 мс (максимально приемлемая задержка, независящая от нагрузки на систему). Средняя мощность, которую может занять 1 экземпляр, по нашим расчетам, составляет примерно 35 мс для обслуживания запроса, при условии, что для обработки запроса не происходит тяжелой обработки. конкретный запрос.


Давайте сгенерируем еще две производные метрики, используя приведенные выше метрики.

  • Емкость : Допустимое отставание на экземпляр: Максимальное количество запросов (нагрузки), которое может быть принято экземпляром без ущерба для 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 таблиц.

  1. Пользователи — для хранения всей информации о пользователях.
  2. Учетные данные — для хранения учетных данных доступа/обновления после авторизации пользователя.
  3. Пароли — для хранения зашифрованных паролей пользователей.
  4. PasswordRequests — для хранения запросов на смену пароля, поступающих для конкретного пользователя.
  5. Сеансы — для хранения информации о том, когда у пользователя был активный сеанс и когда была его последняя активность.
  6. ActivityApproval — для хранения запросов на одобрение действий, выполняемых конкретным пользователем, которые будут проверены администратором.


Высокоуровневый дизайн системы аутентификации

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

Конечные точки системы

Конечная точка

Описание

/авторизоваться

Аутентификация учетных данных пользователя.

/выйти

Завершить сеанс пользователя и отозвать токены аутентификации.

/регистр

Создайте нового пользователя.

/обновление/:идентификатор пользователя

Обновите информацию о пользователе.

/удалить/:идентификатор пользователя

Удалить учетную запись пользователя.

/grant/:userId/:разрешение

Предоставьте пользователю определенные разрешения.

/revoke/:userId/:разрешение

Отозвать разрешения у пользователя.

/check/:userId/:ресурс

Проверьте доступ пользователя к определенному ресурсу.

/создать/:идентификатор пользователя

Создайте новый сеанс пользователя.

/expire/:ИДсессиона

Завершить сеанс пользователя.

/validate/:ИДсессиона

Подтвердите активный сеанс пользователя.


Выполнение требований

Теперь, когда все готово, давайте посмотрим, как мы можем выполнить все требования.


Постановка на учет


  • Требование – Когда новый пользователь посещает наше приложение. Нам необходимо хранить данные пользователя, чтобы мы могли авторизовать/идентифицировать пользователя при следующем посещении.
  • Выполнено — когда новый пользователь посещает приложение и вводит данные пользователя, а также адрес электронной почты и пароль. Это будет зафиксировано в базе данных. Данные пользователя будут храниться в таблице User. А пароль будет храниться в таблице учетных данных в зашифрованном виде.


Авторизоваться

  • Требование — когда существующий пользователь посещает наше приложение. Нам необходимо идентифицировать пользователя, чтобы мы могли авторизовать/идентифицировать его действия и показать им данные, которые им принадлежат.
  • Выполнено — когда существующий пользователь посещает приложение и вводит свои данные, адрес электронной почты и пароль. Мы хешируем пароль и сопоставляем его с хешем, хранящимся для пользователя в таблице учетных данных. Если он соответствует, то мы смогли успешно идентифицировать пользователя. В противном случае им необходимо ввести правильный пароль, который они ввели при регистрации. Этот процесс называется Аутентификация .


Управление сеансами

  • Требование — когда пользователь прошел аутентификацию, введя своего пользователя и пароль. Нам необходимо убедиться, что они остаются в системе, когда выполняют свои будущие действия или пытаются просмотреть конфиденциальные данные, не заставляя их снова и снова вводить свой пароль.
  • Выполнено — когда пользователь успешно проходит аутентификацию. Сервер аутентификации будет делиться с клиентом двумя токенами. access_token иrefresh_token . Access_token может содержать зашифрованные данные и имеет короткий срок действия по соображениям безопасности. Как только клиент получает access_token, он отправляет его обратно вместе с каждым запросом, что помогает аутентифицировать запрос. По истечении срока действия access_token клиент должен запросить новый access_token, используя предоставленныйrefresh_token. Это помогает поддерживать сеанс.


Восстановление пароля

  • Требование . Если пользователь забывает свой пароль, ему необходимо иметь возможность безопасно сбросить пароль.
  • Выполнено — когда пользователь забывает свой пароль, он может указать свой адрес электронной почты на странице забытого пароля, и мы сгенерируем одноразовый код и отправим ссылку на его электронную почту. Когда пользователь нажимает на эту ссылку с кодом и адресом электронной почты. Мы сможем надежно определить, что запрос на восстановление пароля является подлинным. И предоставьте пользователю возможность установить новый пароль. И таким образом иметь возможность восстановить пароль.


Контроль доступа

  • Требование . Когда пользователь выполняет определенное действие, нам необходимо убедиться, что пользователь прошел аутентификацию для выполнения этого действия, и только после этого разрешить выполнение этого действия.
  • Выполнено . Для простоты мы будем сохранять список действий, скажем, от 1 до 12. Для каждого пользователя мы будем поддерживать аутентифицированные действия для этого пользователя. Итак, теперь предположим, что пользователь пытается выполнить действие #id 4. Мы проверим, есть ли у пользователя разрешения на выполнение действия 4. Если да, мы продолжим и выполним запрос. В противном случае мы показываем, что запрос не выполнен из-за отсутствия разрешений.


Аудиторский след

  • Требование . В случае инцидента безопасности у нас должно быть достаточно журналов для просмотра и правдоподобная причина того, что могло произойти, или любые указания на то, что могло быть возможной причиной этого.
  • Выполнено — для таких сценариев мы можем вести журналы для каждого действия аутентификации, происходящего на сервере. (а). Для каждого запроса на вход в систему мы будем вести журнал, в котором будет указано, когда произошла аутентификация, откуда, IP-адреса и другие соответствующие данные. (б). Для каждого запроса на восстановление пароля мы будем вести журнал с указанием того, когда он был инициирован, откуда, IP-адреса, был ли запрос завершен и другие соответствующие сведения. (с). Кроме того, мы будем вести журналы каждый раз, когда пользователь авторизуется/не авторизуется на какое-либо действие и кем. В целом эти журналы должны указывать на то, что могло произойти при попытке понять какой-либо сценарий.


Производительность

  • Требование . Требования к производительности, как описано в разделе оценки емкости, составляют 0,04 запроса в секунду и 100 тысяч запросов в месяц.
  • Выполнено . Мы уже выполнили требование с достаточным количеством серверов в разделе оценки мощности.

Заключение

Аутентификация и авторизация (источник: OutSystems)

В этой статье мы начали с понимания разницы между аутентификацией и авторизацией. Далее мы создали систему аутентификации и авторизации. Это безопасно, надежно, обеспечивает производительность, соответствует отраслевым стандартам и отвечает всем желаемым требованиям. В дальнейшем я мог бы обновить некоторые части статьи, чтобы она оставалась актуальной, а также чтобы охватить больше информации и идей по созданию такой системы.