Реализация технологии SSO на базе Node.js
Веб-приложения создают с использованием клиент-серверной архитектуры, применяя в качестве коммуникационного протокола HTTP. HTTP — это протокол без сохранения состояния. Каждый раз, когда браузер отправляет серверу запрос, сервер обрабатывает этот запрос независимо от других запросов и не связывает его с предыдущими или последующими запросами того же самого браузера. Это, кроме прочего, означает, что получить доступ к серверным ресурсам, которые никак не защищены, может кто угодно. Если нужно защитить от посторонних некие серверные ресурсы, это значит, что нужно как-то ограничить то, что может запрашивать у сервера браузер. То есть — нужно аутентифицировать запросы и отвечать только на те из них, которые прошли проверку, игнорируя те, которые проверку не прошли. Для аутентификации запросов нужно владеть некими сведениями о запросах, хранящимися на стороне браузера. Так как протокол HTTP не хранит состояние запросов, нам для этого нужны некие дополнительные механизмы, которые позволяют серверу и браузеру совместно управлять состоянием соединений. Среди таких механизмов можно отметить использование куки-файлов, сессий, JWT.
Если речь идёт о каком-то одном веб-проекте, то сведения о состоянии конкретного сеанса взаимодействия клиента и сервера легко поддерживать с применением аутентификации пользователя при его входе в систему. Но если такая вот самостоятельная система эволюционирует, превращаясь в несколько систем, перед разработчиком встаёт вопрос о поддержании сведений о состоянии каждой из этих отдельных систем. На практике этот вопрос выглядит так: «Придётся ли пользователю этих систем входить в каждую из них по-отдельности и так же из них выходить?».
Есть одно хорошее правило, касающееся систем, сложность которых со временем растёт, и взаимодействия этих систем с их пользователями. А именно, нагрузка по решению задач, связанных с усложнением архитектуры проекта, ложится на систему, а не на её пользователей. При этом неважно то, насколько сложны внутренние механизмы веб-проекта. Для пользователя он должен выглядеть единой системой. Иными словами, пользователь, работающий с веб-системой, состоящей из множества компонентов, должен воспринимать происходящее так, будто он работает с одной системой. В частности, речь идёт об аутентификации в таких системах с использованием SSO (Single Sign-On) — технологии единого входа.
Как создавать системы, в которых используется SSO? Тут можно вспомнить старое доброе решение, основанное на куки-файлах, но это решение подвержено ограничениям. Ограничения касаются доменов, с которых устанавливаются куки. Обойти его можно, лишь собрав все доменные имена всех подсистем веб-приложения на одном домене верхнего уровня.
В современных условиях таким решениям препятствует широкое распространение микросервисных архитектур. Управление сессиями усложнилось в тот момент, когда при разработке веб-проектов стали использовать различные технологии, и когда разные службы иногда размещались на разных доменах. Кроме того, веб-службы, которые раньше писали на Java, начали писать, пользуясь возможностями платформы Node.js. Это усложнило работу с куки-файлами. Оказалось, что сессиями теперь управлять не так уж и просто.
Эти сложности привели к разработке новых методов входа в системы, в частности, речь идёт о технологии единого входа.
Технология единого входа
Базовый принцип, на котором основана технология единого входа, заключается в том, что пользователь может войти в одну систему проекта, состоящего из множества систем, и оказаться авторизованным и во всех остальных системах без необходимости повторного входа в них. При этом речь идёт и о централизованном выходе из всех систем.
Мы, в учебных целях, собираемся реализовать технологию SSO на платформе Node.js.
Надо отметить, что реализация этой технологии в корпоративных масштабах потребует гораздо больших усилий, чем мы собираемся приложить к разработке нашей учебной системы. Именно поэтому и существуют специализированные SSO-решения, предназначенные для крупномасштабных проектов.
Как организован вход в систему с использованием SSO?
В сердце реализации SSO находится единственный независимый сервер аутентификации, который способен принимать информацию, позволяющую аутентифицировать пользователей. Например — адрес электронной почты, имя пользователя, пароль. Другие системы не дают пользователю прямых механизмов входа в них. Они авторизуют пользователя непрямым способом, получая сведения о нём от сервера аутентификации. Механизмы непрямой авторизации реализуются с использованием токенов.
Вот репозиторий с кодом проекта simple-sso, реализацию которого я здесь опишу. Я использую платформу Node.js, но вы можете реализовать то же самое и используя что-то другое. Давайте пошагово разберём действия пользователя, работающего с системой, и механизмы, из которых состоит эта система
Шаг 1
Пользователь пытается получить доступ к защищённому ресурсу системы (назовём этот ресурс «потребителем SSO», «sso-consumer»). Потребитель SSO выясняет то, что пользователь не вошёл в систему, и перенаправляет пользователя на «сервер SSO» («sso-server»), используя, в качестве параметра запроса, собственный адрес. На этот адрес будет перенаправлен пользователь, успешно прошедший проверку. Этот механизм представлен ПО промежуточного слоя для Express:
Шаг 2
SSO-сервер выясняет то, что пользователь в систему не вошёл, и перенаправляет его на страницу входа в систему:
Сделаю тут некоторые комментарии относительно безопасности.
Вот как может выглядеть список URL служб, которым разрешено использование SSO-сервера:
Шаг 3
Пользователь вводит имя пользователя и пароль, которые отправляются SSO-серверу в запросе на вход в систему.
Страница входа в систему
Шаг 4
SSO-сервер аутентификации проверяет информацию пользователя и создаёт сессию между собой и пользователем. Это — так называемая «глобальная сессия». Тут же создаётся и токен авторизации. Токен представляет собой строку, состоящую из случайных символов. То, как именно генерируется эта строка, значения не имеет. Главное — это чтобы подобные строки у разных пользователей не повторялись, и чтобы такую строку сложно было бы подделать.
Шаг 5
SSO-сервер берёт токен авторизации и передаёт его туда, откуда к нему пришёл только что авторизовавшийся пользователь (то есть — передаёт токен потребителю SSO).
Снова сделаю некоторые замечания о безопасности:
Шаг 6
Потребитель SSO получает токен и обращается к серверу SSO для проверки токена. Сервер проверяет токен и возвращает ещё один токен с информацией о пользователе. Этот токен используется потребителем SSO для создания сессии с пользователем. Эта сессия называется локальной.
Вот код ПО промежуточного слоя, используемого в потребителе SSO, построенном на основе Express:
После получения запроса от потребителя SSO сервер проверяет токен на предмет его существования и срока его действия. Токен, прошедший проверку, считается действительным.
В нашем случае сервер SSO, после успешной проверки токена, возвращает подписанный JWT с информацией о пользователе.
Вот некоторые замечания о безопасности.
После того, как пользователь успешно войдёт в систему, создаются сессии между ним и SSO-сервером, а так же между ним и каждой подсистемой. Сессия, установленная между пользователем и SSO-сервером, называется глобальной сессией. Сессия, установленная между пользователем и подсистемой, предоставляющей пользователю какие-то услуги, называется локальной сессией. После того, как будет установлена локальная сессия, пользователь сможет работать с закрытыми для посторонних ресурсами подсистемы.
Установка локальной и глобальной сессий
Краткий обзор потребителя SSO и сервера SSO
Давайте сделаем краткий обзор функционала потребителя SSO и сервера SSO.
▍Потребитель SSO
▍Сервер SSO
Организация централизованного выхода из системы
Аналогично тому, как была реализована технология единого входа, можно реализовать и «технологию единого выхода». Здесь нужно лишь учитывать следующие соображения:
Итоги
В итоге можно отметить, что существует множество готовых реализаций технологии единого входа, которые можно интегрировать в свою систему. У всех них есть собственные преимущества и недостатки. Разработка подобной системы самостоятельно, с нуля, это — итеративный процесс, в ходе которого нужно анализировать характеристики каждой из систем. Сюда входят способы входа в систему, хранилища пользовательской информации, синхронизация данных и многое другое.
Используются ли в ваших проектах механизмы SSO?
Национальная библиотека им. Н. Э. Баумана
Bauman National Library
Персональные инструменты
SSO (Single Sign-On)
Таким образом ключевым моментом здесь является то, что пользователю требуется войти в систему для подключения к приложению только один раз, причем в контексте этой же сессии нет необходимости проходить аутентификацию повторно при доступе к другому приложению или серверу. [Источник 1]
Содержание
Общая схема систем единого входа
Подход технологии единого входа продемонстрирован на схеме. При этом подходе система может собирать от пользователя (в рамках первичного входа) все идентификационные и аутентификационные данные, необходимые для поддержки аутентификации этого пользователя на каждом из вторичных доменов, с которыми ему потенциально может понадобиться взаимодействовать. Эти предоставленные пользователем данные впоследствии используются сервисами единого входа в пределах первичного домена для поддержки аутентификации этого конечного пользователя на каждом из вторичных доменов, с которыми ему реально требуется взаимодействовать.
Информация, предоставленная конечным пользователем в рамках процедуры входа в первичный домен, может использоваться для поддержки входа во вторичный домен несколькими способами:
С точки зрения управления, модель единого входа предоставляет единый интерфейс управления учётными записями пользователей, через который все домены могут управляться координированным и синхронизированным способом.
С точки зрения интеграции, важнейшие аспекты безопасности модели единого входа заключаются в следующем:
Основные достоинства и недостатки SSO
| Достоинства | Потенциальные недостатки |
|---|---|
| Снижение времени, требуемого для повторного ввода паролей; | Попытка первоначальной реализации может быть сложной, в зависимости от количества существующих не сопоставимых систем |
| Снижение количества паролей, необходимых для различных программных продуктов; | Скомпромитированные входные данные (credentials) пользователя могут привести к доступу к большому числу приложений |
| Снижение нагрузки на сеть, связанной с многократными процедурами аутентификации; | Производитель либо не использует существующий открытый стандарт, либо использует стандарты, несовместимые со стандартами, используемыми другими приложениями. |
| Снижении стоимости IT-системы за счет снижения количества инцидентов ИБ, связанных с учетными данными пользователей; | Данный механизм требует установки специальных агентов, поддерживаются не все устройства и операционные системы. |
Методы SSO
Технология единого входа включает в себя следующие методы:
Основные преимущества SSO
| Преимущества для конечных пользователей | Преимущества для администратора безопасности |
|---|---|
| Необходимо хранить в памяти только один механизм аутентификации. Для аутентификации на основе пароля это означает, что пользователям надо помнить только один пароль | Запись регистрационных данных пользователя в одном месте для управления и обеспечения безопасности. |
| При употреблении паролей пользователи должны изменять только один пароль и следовать только одному набору правил паролирования. | Возможность ведения общих для организации политик паролирования и обеспечения безопасности, позволяющих обеспечить «сквозную» безопасность, возможно в рамках приложений и систем. Это позволит избежать проблем с несоответствием требований по сложности паролей и периодам их смены в различных системах. |
| Единственный вход для каждого пользователя в домене SSO, обычно только один раз в день. | Проще контролировать информацию о правах доступа пользователя (user security information) и при необходимости корректировать ее, чем при отслеживании всех отдельных систем, к которым имеет доступ пользователь. Это особенно важно, когда пользователям назначают роли с другими уровнями доступа. |
Протоколы, обеспечивающие технологию единого входа
На данный момент существует множество протоколов, которые обеспечивают технологию единого ввода. Рассмотрим лишь некоторые из них:
Протоколы семейства WS-
Данный протокол основывается на стандартах WS-Security и WS-Trust и описан в спецификации WS-Federation Passive Requestor Profile, в которой представлены механизмы для запроса, обмена и выдачи маркера безопасности в ситуации с пассивным клиентом. Определение «пассивный клиент» подразумевает наличие на компьютере пользователя только веб-браузера, так как взаимодействие между пользователем, Центр Идентификации и Целевое Приложение (веб-сервер, предоставляющий ресурсы) происходит в пределах функциональности базы HTTP (методы GET, POST, перенаправления и cookies). Схема протокола имеет следующий вид:
С учетом требований, описанных в спецификации WS-Federation Passive Requestor Profile, протоколом поддерживаются следующие форматы маркеров безопасности:
Протокол SAML
SAML (англ. security assertion markup language — язык разметки декларации безопасности) — язык разметки, основанный на языке XML. Открытый стандарт обмена данными аутентификации и авторизации между участниками, в частности, между поставщиком учётных записей (англ. identity provider) и поставщиком сервиса (англ. service provider). SAML — продукт OASIS, разработанный Техническим комитетом безопасности сервиcов. SAML создан в 2001 году; последнее значимое обновление SAML было опубликовано в 2005 году, но расширения протокола постоянно выпускались через дополнительные, опциональные стандарты.
Одной из важных проблем, которую пытается решить SAML, является обеспечение сквозной аутентификации при работе через Web-браузер. Использование SAML в качестве технологии единого входа на уровне сети (intranet) распространено (например, с использованием cookies), но расширение за пределы частной сети (intranet) было проблематично и привело к созданию несовместимых запатентованных технологий (другой, более современный подход обеспечения SSO — это протокол OpenID)
Протокол OpenID
OpenID — открытый стандарт децентрализованной системы аутентификации, предоставляющей пользователю возможность создать единую учётную запись для аутентификации на множестве не связанных друг с другом интернет-ресурсов, используя услуги третьих лиц.
Аутентификация посредством OpenID [FH07] обеспечивает возможность подтвердить, что пользователь обладает идентификатором без запроса доверенной стороной у пользователя его идентификационных данных, таких как пароль или адрес электронной почты. OpenID – децентрализованный протокол, пользователь может выбрать идентификатор какого провайдера OpenID предоставить. Для поддержки данного протокола требуется только JavaScript или современный веб-браузер. OpenID использует только стандарты HTTPS, то есть не требует никаких специальных возможностей клиентского программного обеспечения. Основными элементами процесса аутентификации являются:
Идентификатор OpenID – это строка, которая является уникальной для каждого пользователя. Один идентификатор не может принадлежать более чем одному пользователю. Различают следующие два вида идентификаторов:
Клиент OpenID (ЦП) – онлайн – ресурс (чаще всего веб-сайт, но им также может быть файл, изображение или любой ресурс, к которому необходимо контролировать доступ), который использует OpenID для идентификации обращающихся к нему пользователя.
Провайдер OpenID (ЦИ) – сайт, на котором пользователи могут получить идентификатор OpenID. Данный сайт может в будущем авторизовывать и аутентифицировать пользователей, обращающихся к Целевому Приложению. Провайдер OpenID также предоставляет веб-интерфейс для управления выданными идентификаторами.
Схема протокола выглядит следующим образом:
Протокол OAuth
Схема протокола имеет следующий вид:
Протокол OAuth является широко распространенным, благодаря его использованию сервисами поисковых систем, почтовыми сервисами, а также в социальных сетях.
Single Sign-On, или Танцы Шестерых
Материал прозаичен, но может оказаться кому-нибудь полезным, чему я буду очень рад. Ещё больше буду признателен конструктивным советам и отзывам.
Итак, наша тема – «Как реализовать Single Sign-On для веб-приложения в условиях разношёрстности и нормальной лохматости системного зоопарка».
Single Sign-On. Вводная
Доверился кому, так доверяй во всём.
© Цецилий Стаций
Для тех, кто не в курсе (хотя они вряд ли станут читать этот материал), скажу, что Single Sign-On (в дальнейшем повествовании – «SSO») в общепринятом представлении не является ни технологией, ни тем более неким магическим протоколом. SSO – это подход, метод, позволяющий реализовать связность AAA (Authentication & Authorization & Accounting) между разнородными системами и приложениями без дополнительных телодвижений со стороны конечного пользователя.
Типичными примерами SSO являются, например, решения, построенные целиком на продуктах Microsoft; в этом случае сервер(ы) Active Directory обеспечивают не только хранение каталога, но и управляют поведением подключенных к домену рабочих станций, установленным на них софтом и всем прочим, вплоть до железа (мы же все умеем запрещать политиками тот же USB). Сквозная парадигма AAA в такой ситуации обеспечивается почти автоматически при использовании продуктов Microsoft, то есть в гомогенной среде.
В качестве примеров:
Аксиома
Задача
Сразу оговорюсь, что есть и более простые пути решения этой задачки, помимо описанного ниже, но мы же их не ищем. Ну и требования Заказчика были не самые однозначные.
Танцуем с Пингвинами. Linux
Домен: Эукариоты, Царство: Животные, Подцарство: Эуметазои, Тип: Хордовые, Подтип: Позвоночные, Инфратип: Челюстноротые, Надкласс: Четвероногие, Класс: Птицы, Подкласс: Новонёбные, Отряд: Пингвинообразные, Семейство: Пингвиновые, Вид: Oracle Linux Server release 7.2
Установка
Нам достался вполне оперившийся потомок/клон RHEL под именем Oracle Linux Server release 7.2.
Настройка
Как всегда, Линукс в его серверном виде прост, беззаботен и безотказен, но нам важно убедиться, что он правильно сконфигурирован, особенно в части сетевых настроек.
Тестирование
Сначала смотрим на настройки DNS, т.к. это критично для работоспособности всего решения:
На этом этапе необходимо проверить доступность серверов DNS (которые, в нашем случае, являются и домен-контроллерами). Сделать это можно по-разному, просто используйте свои любимые утилиты и методы проверки (host, dig, telnet, ping, …). Важно, чтобы нужные нам порты были доступны и работоспособны, а в случае DNS это в первую очередь TCP/53. И не забываем про кощунство и жадность сетевых администраторов и безопасников (я сам такой), которые могут закрыть вам всё, включая ICMP, и оставить только парочку затребованных и согласованных портов. Что есть правильно.
Собачий вальс. Kerberos
Це́рбер, также Ке́рбер (от др.-греч. Κέρβερος, лат. Cerberus) — в греческой мифологии порождение Тифона и Ехидны (Тартара и Геи), трёхголовый пёс, у которого из пастей течёт ядовитая смесь. Цербер охранял выход из царства мёртвых Аида, не позволяя умершим возвращаться в мир живых. Однако это удивительное по силе существо было побеждено Гераклом в одном из его подвигов.
Уверен, что не нужно напоминать про необходимость правильной настройки Kerberos для «плодотворного сотрудничества» с MSAD.
Разумеется, для установки и конфигурирования вам необходимы root’овые права на сервере. Или sudo. Или «Звоните Солу».
Установка
Установка и настройка необходимых пакетов производится довольно просто, если «злые сетевые админы» дали вашему серверу выход в Интернет.
К сожалению, Интернет с доступом к репозиториям нужен на этапе установки, если добрые админы не установили всё нужное заблаговременно.
И всё печально, если нет ни доступа, ни установленных пакетов.
Однако будем оптимистами и, считая, что админы хотя бы на часик открыли канал, выполняем установку:
Само собой, как используемый менеджер пакетов, так и их версии у вас могут быть другими, но сути дела это не меняет.
И Да, обещаю, что более таких наиполнейших листингов тривиальной установки в статье не появится.
Настройка
Вполне работающий файл конфигурации Kerberos изначально будет выглядеть примерно так:
Тестирование
На следующем шаге у нас, как правило, всё происходит очень просто.
Просто убеждаемся, что всё плохо:
Зовём специалистов по трёхголовым собачкам (AKA сисадмина, знающего сверхсекретный доменный админский логин/пароль), и просим его ввести его примерно вот так:
После этого klist должен вернуть уже что-то осмысленное.
Засим нашу собачку считаем готовой, хотя…
Общеизвестно, что Ниссан – это невыгулянный Пассат.
Танец Великих Равнин. Apache
Апачи – собирательное название для нескольких культурно родственных племён североамериканских индейцев, говорящих на апачских языках атабаскской ветви семьи на-дене.
Апачи создали свой собственный захватывающий танец в масках по названию гахан, которым они празднуют достижение совершеннолетия девочками. Также у апачей и поныне есть танцевальные обряды для видений и предсказаний.
Начинаем охотиться вместе с индейцами племён Апачи.
Установка
Как и прежде, пакеты – это наше всё (за исключением всемогущих шаманов-Админов, разумеется):
Настройка
Этого, конечно, недостаточно, потому что свежеустановленный индеец не знает нашего языка. Сконфигурируем его примерно так:
И дадим “пиночек под задочек”:
Убедимся, что он научился разговаривать по-нашенски, зайдя в System Management Portal.
Апачи некогда были гордым и независимым народом, у них это в крови, поэтому со всем уважением и вежливостью попросим Apache браться за работу вместе с нашим Пингвином-Прорицателем:
Прослушавши “Пионерскую Зорьку”, сделав водные процедуры, выгулявши трёхглавую собачку и причесав индейца, переходим к “Производственной Гимнастике”, которая сегодня будет танцевальной (и даже с бубнами).
Танцуем Самбу!
Са́мба (порт. samba) — бразильский танец, символ национальной идентичности бразильцев. Танец обрёл мировую известность благодаря бразильским карнавалам. Одна из разновидностей самбы вошла в обязательную пятёрку латиноамериканской программы бальных танцев. Исполняется в темпе 50-52 удара в минуту, в размере 2/4 или 4/4.
Как всем нам прекрасно известно, наша любимая Samba в серверном варианте совершенно логично разделена на три основных исполняемых модуля: (smb|nmb|winbind)d.
Теоретически нам нужен только работоспособный winbindd. Да, это всего лишь один из демонов Самбы. Но он, установленный отдельно от всего пакета, почему-то на имеющейся платформе работать не захотел, а разбираться в причинах его недовольства не захотелось уже мне.
Поэтому устанавливаемся по полной.
Установка
Процедура очень проста, особенно, если ваш(а) Админ(ша) танцует вместе с вами.
Костюмчик готов, затягиваем галстук:
Настройка
Мало прийти на карнавал, нужно ещё и немного потанцевать (уже с бубнами):
Репетируем первые шаги (разумеется, ошибаемся на первых порах):
Зовём на помощь учителей танца, и («Как много нам открытий чудных. ») это оказываются те же самые кинологи, помогавшие нам в приручении нашего трёхглавого щеночка!
И надеемся на чудо… Всё зависит от рук и от места, откуда они растут…
«Разлук так много на земле.
И разных судеб,
Надежду дарит на заре.
Паромщик людям”
© Prodigy & Rammstein, 2048
Если затем видим примерно вот такое:
то Счастье уже почти Есть!
Тестирование
Проверяем его (Счастья) наличие:
Медляк. mod_auth_ntlm_winbind
Прежде чем танцевать медленный танец, придется кого-то на него пригласить, ведь в одиночку под него двигаться не считается приемлемым. Улучите момент и подойдите к приглянувшейся девушке. Собравшись танцевать медленный танец, объявите о своем намерении потенциальной партнерше прямо, без ненужного многословия. Не будьте излишне развязны и напористы, оставьте за ней решение, согласиться или нет. В последнем случае она откажется, но поблагодарит вас.
Установка
Найдите в Сети живой репозиторий с mod_auth_ntlm_winbind.
Да, их мало живых (я забрал с какого-то svn).
Да, версии совсем не новые.
Да, вам нужно будет их собрать «вручную».
Да, не все соберутся.
Да, даже после патчей и правок вручную.
Да, для сборки понадобится полностью настроенное окружение (gcc + glib + apxs + headers + *-dev + …).
И ДА, это – единственный известный мне вариант, который работает стабильно.
Настройка
С настройкой всё более-менее элементарно, добавьте в ваш конфиг-файл Apache (в основной, либо в conf.d/xyz.conf, по желанию):
Разумеется, пути должны быть указаны правильно для вашей инсталляции, как и все прочие параметры.
Для первоначальной отладки советую раскомментировать строчку LogLevel, тогда в файлы протоколов Apache будут записываться дополнительные и иногда очень полезные сообщения.
Белый танец. Кто кого.
Leicht versprochen, leicht gebrochen.
На очень закономерный и весьма своевременный (к концу статьи-то!) вопрос «А нафига мы всё это делали?» отвечу, что всё это всего-то ради одной строчки в серверном ответе HTTP.
Бочка мёда
Нам нужен верный автоматически передаваемый веб-сервером REMOTE_USER (или HTTP_REMOTE_USER – не суть важно), чтобы:
После этого мы запросто сможем с серверной стороны используя, например, LDAP-доступ к AD, запросить иные реквизиты этого пользователя (членство в группах, и т.п.).
Про эту механику планируется отдельная статья, там есть свои тонкости.
Парочка ложек дёгтя
Single Sign-On. Выводная
Я буду весьма признателен, если подскажете в комментариях более удачную конфигурацию; допускаю даже, что появилась новая механика взаимодействия AAA для связки Linux + Apache + MSAD, про которую я не знаю.




