Реализуем идеальную аутентификацию в вашем JS-приложении

По материалам доклада на JS Fest Autumn 2019, Киев

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

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

Для начала давайте определимся с разницей между аутентификацией и авторизацией.

Аутентификация — процесс установления личности пользователя.

Авторизация — процесс установления прав этого пользователя относительно какого-то ресурса.

При правильном подходе к реализации аутентификации нужно учесть все возможные «скользкие места». Это могут быть:

  • потенциальные уязвимости (security);
  • риски;
  • стоимость реализации.

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

  • Registration flow — регистрация пользователя (за исключением B2B систем, где часто пользователю предоставляют данные для аутентификации).
  • Password reset flow — путь сброса и восстановления пароля.
  • Credentials validation — валидация имени, пароля пользователя, а также других данных, которые у вас есть.
  • Error handling — правильная обработка ошибок.
  • Error messages — вывод сообщений об ошибках.
  • Localization — настройка локализации этих сообщений.
  • Brute-force attacks protection — возможность оперативно реагировать на попытки взлома, DDOS-атаки, а также предотвращать их.
  • Email template — создание красивого шаблона письма с регистрационными данными юзера.

Дополнительно желательно настроить:

  • Функцию «Remember me».
  • Возможность блокировки пользователей.
  • Журнал событий — чтобы знать, кто заходил в приложение и что он там делал.
  • Выявление аномалий. Например: пользователь только что зашел из Киева, а через 5 минут — из Лондона, как он так быстро переместился?
  • Мультифакторную аутентификацию.
  • Глобальный выход из системы — чтобы прекратить сессии на всех устройствах пользователя.

Если говорить о мире JavaScript, то есть безоговорочный лидер среди библиотек для аутентификации. Это — Passport.js. Данная библиотека, по заявлению разработчиков, поддерживает около 500 разных стратегий (способов) аутентификации. Использование Passport.js существенно упрощает разработку, но все же, при использовании внешних сервисов для аутентификации, требует разбираться с особенностями каждого сервиса.

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

Плюсы:

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

Минусы:

➖Если в готовом решении что-то не работает или не подходит именно вам, вы остаетесь с проблемой один-на-один.
➖Очень крутая кривая обучения. Ведь у готового продукта, как правило, много документации, с которой нужно будет ознакомиться. Для этого нужно время. Кроме того, обычно ценники на те решения, которые вы можете разместить у себя и которые являются проприетарными, на порядок выше, чем аналогичные облачные сервисы. Вы платите за лицензию, и вам также нужно подумать про highly available инфраструктуру. Необходимо найти DevOps специалиста или администратора, а также команду людей, которая будет это поддерживать. Это потянет значительные расходы.
➖Зависимость от конкретного вендора. Кто-то готов использовать стандартный протокол (например, OpenID Connect). К сожалению, до того момента, как ваше приложение будет интегрироваться с этим стандартным протоколом, вам придется сделать много специфичных задач для этой платформы, и таким образом получить зависимость от вендора.
На рынке имеется несколько популярных решений — как проприетарных, так и опенсорсных.

Из опенсорсных это:

  • Shibboleth
  • Keycloak
  • WSO (хоть и написано на Java, но для JS можно взять его Identity Management, который является standalone модулем)

Из проприетарных довольно популярен FusionAuth.

При выборе selfhosted решения, мы обычно стараемся найти что-то опенсорсное. Ведь чаще всего не хочется платить за лицензию, а также удобнее использовать продукт на предсказуемых условиях. Важно помнить, что бесплатный ≠ свободный продукт и наоборот. Ведь лицензию могут поменять в любой момент, или же бывает двойное лицензирование, когда комьюнити фичи лежат в публичном доступе, а необходимые функции является частью enterprise/premium предложения с высоким ценником.

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

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

У таких решений имеется много достоинств:

  1. Почти нулевой time to market: купить подписку на сервис, добавить минимальное количество кода в свое приложение, и все — у вас уже есть аутентификация. Не нужно думать о том, как это поддерживать, как масштабировать.
  2. Плата за каждого юзера. Очень удобно, например, если вы стартап на ранней стадии и пользователей у вас 0, то и платить ничего не нужно.
  3. Не нужно тратить время и деньги на реализацию.
  4. Не нужно это все поддерживать и сопровождать.
  5. Тесная интеграция с облачными платформами. Если вы используете Firebase Auth или AWS Cognito — это хорошо интегрируется с вашей облачной платформой. В основном это значит, что вы сможете сэкономить. Потому что если ваша аутентификация и авторизация интегрируется с вашим облаком, возможно, вам не нужно будет думать о доступах к своим ресурсам. Например, в AWS Cognito вы можете ограничить доступ к базам данных либо к части базы данных просто на основании того факта, что ваш юзер хранится в Cognito, т.е. вы избавляетесь от большого количества кода. Кроме того, вся эта логика выполняется на инфраструктуре вашего облачного провайдера, вы для этого не пишете код, не хостите его, а значит — вы за это не платите(по крайней мере, напрямую).
  6. Гибкие в плане GDPR и многих других стандартов, которые связаны с личными данными. Аутентификация часто происходит с использованием личных данных, а также эти данные могут хранится как часть информации о пользователе. Вскоре вы зададитесь вопросом, как сделать продукт совместимым с GDPR? Одно из требований GDPR и подобных регуляций — это хранить данные в зашифрованном виде (иногда и в определенном).
  7. Если вы писали решение сами или делали self hosted решение, вам нужно будет поднять вашу инфраструктуру физически в каком-то дата-центре и поддерживать ее там.
  8. В случае с облачными провайдерами — зайти в админку и нажать галочку, чтобы данные пользователей хранились в Европе.

Недостатки подхода:

  1. Плата за каждого пользователя. Если на этапе стартапа это преимущество, так как у вас еще нет пользователей, то когда вы подрастёте, это потянет нехилый бюджет.
  2. Вы не поддерживаете сервис, он масштабируется автоматически. Сервис практически никогда не «падает», но если вдруг «упадет», то «лежит» серьезно, пока его не поднимут вендоры, хоть обычно это происходит достаточно быстро.
  3. Проблемы с настройкой под себя. Если вам нужно будет использовать ваше лого, фирменные цвета и т.д., заранее подумайте, можно ли такое реализовать в готовом решении и
  4. можно ли вендора «убедить» предоставить вам такую возможность.

Краткий обзор сервисов облачной аутентификации

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

  • Okta
  • Auth0
  • AWS Cognito
  • Firebase Authentication

Из всех вышеперечисленных сервисов, Okta, является наименее «хипстерским», самым дорогим, и у них, наверное, наибольшее количество фич, таких как управление пользователями для облачных приложений, возможность менеджмента пользователей через active directory.

Обзор сервиса Auth0

Преимущества Auth0

  • Разработан компанией, специализирующейся на authentication и authorization сервисах.
  • Хорошо интегрируется с разными платформами и языками.
  • Предоставляет Hosted UI.
  • Client-side и server-side SDK.
  • Поддержка MFA.
  • Passwordless/One-time-password (OTP) sign-in.
  • Self-hosted для enterprise решений.

Слабые стороны AWS Cognito

  • Standalone продукт, требует дополнительной интеграции в вашу инфраструктуру.
  • Не быстрый саппорт для базовых подписок.
  • Мощный сервис, но несколько сложный.
  • Поддержка HIPAA и других стандартов только для enterprise лицензий.

Auth0 предоставляет только аутентификацию и авторизацию (как и в Okta, все остальное идет в связке с каким-то облачным провайдером). Имеет глубочайшую экспертизу и широкий спектр инструментов. Легко интегрируется со множеством платформ, с разными языками, у него много SDK и библиотек. Если у вас какой-то достаточно экзотичный язык, то Auth0, скорее всего, его поддерживает. Если вы используете нестандартные клиентские фреймворки — вполне вероятно, что для Auth0 либо уже есть решение, либо кто-то над этим работает. Очень легко кастомизируется. Есть готовая Hosted UI. В сервис можно добавить MFA, так как это очень хорошо для безопасности. Есть и такая интересная штука, как Passwordless/OTP sign-in (одноразовый пароль). Сервис можно использовать как облачное решение, а можно захостить у себя в инфраструктуре, однако стоит это недешево.

Из недостатков Auth0 хочется упомянуть то, что вся интеграция с вашей инфраструктурой лежит на вас. Если нужно что-то проверить или поменять — нужно лезть в Auth0 через API. Для небольших компаний это не страшно. На больших масштабах сложнее, так как тут играет роль специфика работы с современными облачными провайдерами. Входящие данные — бесплатно. Запросы к сторонним ресурсам — платно. Поскольку при авторизации и аутентификации подобные запросы мы будем делать часто, это влетит в копейку.

Также стоит помнить, что в дешевых тарифных планах support отностительно труднодоступен. И HIPAA compliance есть только в дорогом тарифе Enterprise.

Обзор AWS Cognito

Преимущества AWS Cognito

  • Предоставляется как часть платформы Amazon Web Services(AWS).
  • Поддерживает OIDC и SAML Federation.
  • Поддерживает web, iOS и Android клиенты.
  • Предоставляет client-side и server-side SDK.
  • Хорошо интегрирован с AWS сервисами и может выдавать токены для доступа.
  • Поддерживает Hosted UI.
  • Поддерживает MFA.
  • Совместим с HIPAA, PCI DSS стандартами «из коробки».

Слабые стороны AWS Cognito

  • Hosted UI слабо кастомизируется по сравнение с конкурентами.
  • API работает очень медленно.
  • Низкие API rate limits(можно увеличить через техподдержку).
  • Search API неудобный, разве что вам достаточно базового поиска по имени и e-mail.
  • Очень мало готовых интеграций с внешними системами.

Обзор Firebase Authentication

Преимущества Firebase

  • Хорошо интегрирован с Google Firebase.
  • Предоставляет SDK для многих платформ, включая C++ и Unity.
  • Гибкая конфигурация email адресов и email actions.

Слабые стороны Firebase

  • Не поддерживает HIPAA стандарт (но есть альтернативные решения).
  • Не поддерживает SAML «из коробки».

При выборе облачного сервиса рекомендуется подумать над следующим:

  1. Какие платформы поддерживаются, чтобы потом дополнительно не писать клиентские библиотеки под сервис.
  2. Если это существующее приложение, необходимо подумать о том, как импортировать туда текущих юзеров, чтобы воссоздать его уже в облаке. Обычно облачные сервисы используют для этого batch импорт. Это не очень хорошее решение, ведь в таком случае вы даете сервису CSV-файл, он его обрабатывает, и в итоге ваши пользователи получают e-mail, в котором их просят сбросить пароли. Такие сообщения могут выглядеть настораживающе для пользователей, поэтому нужно хорошо обдумать процесс перехода.
  3. Как можно сделать резервную копию данных пользователей с облачного сервиса. Такие сервисы не отдают данные по паролям, так как в таком случае это уже нарушило бы все требования безопасности. В случае резервной копии, скорее всего тоже придется попросить пользователей сбросить пароль.
  4. Потенциальные финансовые риски, которые станут очевидными в тот момент, когда вы начнете развиваться и расти. Например, плата за пользователя при переходе с базовой версии сервиса на более продвинутую. Иногда отличается в десятки раз.
  5. Как часто «падает» сервис и насколько доступна вам поддержка. В бюджетных версиях сервисов очень часто с ней можно связаться только по email и получить ответ только через несколько дней.

Сколько стоят облачные сервисы

Количество пользователей Auth0AWS CognitoOktaFirebase
1K$23/mo$0/mo$0/moFree
10K$228/mo$0/mo$200/moFree
50K$1140/mo$0/mo$100/moFree

Может показаться, что более $1000 за 50к пользователей — это дорого. Но на самом деле, если вы не делаете соц. сеть и у вас продукт монетизируется — каждый пользователь приносит деньги. И лучше включить эту сумму в стоимость подписки, чем внедрять решение самостоятельно.

У AWS Cognito до 50 тысяч пользователей стоимость сервиса составляет $0, но стоит помнить, что вам придется платить за API.

У Firebase все полностью бесплатно, потому что у них Firebase Authentication попадает в категорию бесплатного сервиса.

Как принять окончательное решение

Помните, что если есть такая возможность, то всегда лучше выбрать облачный подход. Если вы являетесь агрегатором новостей, социальной сетью или крупным порталом — делайте агрегацию, а аутентификацию купите. Если же есть какие-то жесткие регуляции в компании, возможно вы банк или государственное учреждение, у вас может не быть выбора, и вам придется использовать open source вместе проприетарного решения. Если ничего из этого не подходит или если нужно сделать proof of concept — пишите решение самостоятельно.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось2
До обраногоВ обраному11
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

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

Убежден, что авторизация — это вещь простая, главное хранить не в открытом виде пароли

1. Авторизация вообще не имеет ничего общего с паролями.

2. Рядом стоят два классных авто одной марки. Владелец одного авто предпринял все меры, чтобы обезопасить машину от угона. Владелец второй — спрятал ключи в «надежном» месте. Задачка на подумать: какую машину угонят первой?

угонят ту которую предпринял все меры — потому что предприняли все меры, а тот который ключ под ковриком — и брать то нечего ) Смотрите ваша мысль ясна — вы правы конечно, нужно делать все, чтобы авторизация была надежнее, но вы описываете пример, где нужно потратиться, пожертвовать производительностью, потратить в 10 раз больше времени на реализацию. Авторизация самая примитивная по надежности не будет отличаться на выходе от вашей, потому что в любом случае, если она будет ломаться кем то высокого ранга, то сломается и та и та. Зачем платить больше ) ну как то так.
Нужно вкладываться в другое — настраивать правильно сервера где хранятся данные, пинать на сутки и более в бан, если больше 2 попыток входа по неправильному паролю, хранить в шифрованом виде без обратной транспортировки пароли, и все будет гуд.
Большинство взломов авторизации через хило настроенный сервер, а не через авторизацию как таковую.
Но в любом случае завидую вашей усидчивости, вы проделали большую работу. Но я уклон делаю на другие вещи, здесь мы с вами расходимся.

Евгений, вы не поняли сути. Пока вы будете

вкладываться в другое — настраивать правильно сервера где хранятся данные, пинать на сутки и более в бан, если больше 2 попыток входа по неправильному паролю, хранить в шифрованом виде без обратной транспортировки пароли, и все будет гуд.

Кто-то просто будет использовать Auth0/Okta/Cognito/Firebase за ~10 долларов в месяц и получит это из коробки мгновенно.

Если вы — маленький стартап, который не связан ограничениями всякого разного рода compliance & regulations, дешевле взять готовое решение. Потому-что своё, в 99% случаев, будет самописный велосипед на коленке.

нужно делать все, чтобы авторизация была надежнее, но вы описываете пример, где нужно потратиться, пожертвовать производительностью, потратить в 10 раз больше времени на реализацию.

Мне кажется, вы не уловили суть. В статье/докладе, как раз, я говорю о совершенно противоположных вещах.

Дякую за статтю!

у вас какая-то путаница в разделе «Обзор сервиса Auth0», преимущества точно такие как у Когнито, а в cons написано «Слабые стороны AWS Cognito»...

В блоке про Auth0, в заголовке про Слабые стороны Auth0, указано Слабые стороны AWS Cognito

не видно виправлень, досі

Слабые стороны AWS Cognito

у розділі про Auth0.

Чудова стаття, дякую.

Є пара зауважень:

— В опису AuthO: «Слабые стороны AWS Cognito»
— Немає обзору Okta, хоча вона є в порівняльній таблиці.

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

как только решаешь прикрутить MFA или даже «сброс всех сессий», вечер перестает быть томным. Пусть и не рокет-сайнс, но задача очень обширная, богатая на нюансы и поиск компромиссов.

Прям настолько обширная что нужно привязаться к стороннему сервису и платить абонплату. Ну не знаю.

как только решаешь прикрутить MFA или даже «сброс всех сессий»

по сути велисипедостроение, ибо нужно разок сервис написать, и носить в докере по проектах, это ведь унифицированная задача

золотые слова! конечно, если планируются еще минимум с пяток проектов под это, требования идентичные, а других задач нет.

Из популярных сервисов для облачной аутентификации можно выделить:
Okta
Auth0
AWS Cognito
Firebase Authentication
Из всех вышеперечисленных сервисов, Okta, является наименее «хипстерским», самым дорогим, и у них, наверное, наибольшее количество фич, таких как управление пользователями для облачных приложений, возможность менеджмента пользователей через active directory.

И каким из этих сервисов должны пользоваться те, кто хостятся в Azure?

К сожалению, практически не сталкивался с Azure. Подозреваю, что наиболее подходящий сервис от Azure — Azure Active Directory.

Из «неродных» Auth0, Okta — они совершенно не привязаны к конкретному провайдеру облачных вычислений.

Причём, у Azure AD была даже своя родная библиотека для JavaScript (adal.js, если склероз не изменяет)

AzureAD, если недостаточно для некоторых аппок — можно «вставить» перед ним Auth0 как первичный IdP с интерктивной страницей / перехватывающим кодом чтобы сделать пару раундтрипов самла к ажуре, шиболету или еще чему (+ надо еще учесть гемор с хэшевой частью урла — пост и джс, чтобы сохранить фрагменты в куки)
страшненько но энтре(>500k корпоюзерков)пайзненько

Отличная статья! Как раз то что ожидается на этом ресурсе 😊

Всем, кому интересны технические статьи на ДОУ стоит подписаться на наш специальный телеграм-канал:
t.me/dou_tech

А что оно вообще делает на форуме, почему не в ленте?

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

Спасибо за обширный обзор!

Підписатись на коментарі