Всем привет! Меня зовут Екатерина Срибна, я Full Stack Developer в NIX. В этой статье я решила сравнить популярные инструменты аутентификации и авторизации, которые упростят работу с технологией единого входа — Single Sign On. Собранный мною материал будет полезен для новичков и специалистов с опытом. Статья ориентирована в основном на .NET-разработчиков, но есть здесь инсайты и для работающих с Java и JavaScript.

Что такое Single Sign On

Технология единого входа (Single Sign On) значительно упрощает жизнь пользователей. Для перехода между разными сервисами, количество которых растет день ото дня, достаточно одной аутентификации и авторизации. Сложность только в том, что Identity-провайдеров, которые поддерживают Single Sign On, существует много. На старте может быть не понятно, какой провайдер лучше выбрать, как его использовать и настраивать у себя на проекте. Эта статья поможет вам во всем разобраться. Мы познакомимся с IdentityServer 4, рассмотрим Azure B2C и интегрируемся с Keycloak.

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

Под аутентификацией мы понимаем идентификацию пользователя, наличие у него идентификатора (логин, e-mail и т.п.), и при этом мы доверяем Identity-провайдеру, который выдал эту информацию. А уже чтобы пропустить пользователя, проверить его доступы, мы обращаемся к авторизации. Обычно этот механизм использует распределение скоупов и ролей для пользователей.

Благодаря технологии Single Sign On этот процесс упрощается. Пользователь может всего один раз авторизоваться и ходить между ресурсами без повторного введения своих кредов, вспоминая пароли. Проверка пользователя происходит «под капотом» системы.

Рассмотрим принцип Single Sign On на следующей схеме. Есть пользователь, есть его браузер, и пользователь взаимодействует с ним, чтобы постучаться на первый сайт. Также есть Identity-провайдер, который мы настроили. У сайта есть ключ, по которому он может валидировать всю информацию, получаемую от Identity-провайдера, с которым установлены доверительные отношения.

Пользователь отправляет запрос на получение данных какого-то ресурса, но этот ресурс требует авторизации. Далее сайт 1 с помощью пользовательского браузера через  редирект отправляет запрос на Identity-провайдер, чтобы получить информацию о пользователе. Identity-провайдер смотрит, что у него нет никакой информации по этому запросу, он не знает, авторизован пользователь или нет, и выдает логин-страницу для него. Пользователь вводит свою информацию. Identity-провайдер ее валидирует и как бы говорит «О, все, привет! Я тебя вижу и знаю тебя», а затем отправляет токен обратно через пользовательский браузер редиректом на сайт. После валидации токена сайтом, выдаем пользователю ресурс и с ним — свои cookies. В будущем мы таким образом упростим взаимодействие нашего сайта и пользователя.

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

У этого подхода к аутентификации и авторизации есть два ключевых преимущества:

  • Удобство для пользователя. Он один раз залогинился и получил доступ ко всем необходимым ресурсам без постоянных переходов по разным логин-страницам.

  • Простота менеджмента. Мы со своей стороны можем централизованно управлять доступами. То есть в одном месте настраиваем пользователей, их доступы, роли, скоупы ресурсов и т.д. Это очень удобно для администрирования приложений.

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

Способы реализации flow, которые поддерживает OAuth 2.0

Протоколов для настройки аутентификации и авторизации достаточно много: OpenID Connect, OAuth 2.0, SAML и WSFed. Я остановлюсь на первых двух.

OpenID Connect — это надстройка над OAuth 2.0, которая позволяет проводить верификацию пользователя с помощью авторизационного сервера. Для аутентификации и авторизации пользователей мы можем подключать разные клиенты, веб- и мобильные приложения, JavaScript-клиент для получения информации об авторизационных сервисах и т.д.

Сам же OAuth 2.0 — это протокол авторизации, отвечающий за проверку доступов пользователя. В протоколе OAuth 2.0 есть разные flow для того, чтобы сделать механизм авторизации, который будет указывать, откуда получать информацию и какую конкретно, что и где сохранять:

Client Credentials Flow (он же Machine to Machine или Service to Service). С помощью этого flow можно настроить аутентификацию и авторизацию между несколькими сервисами. Причем не будет никакого взаимодействия с пользователем.

Device Authorization Flow. Подходит для приложений, которые должны работать еще на каком-то устройстве. То есть это не обязательно веб-приложение, а, например, приложение на Smart TV. В нем есть разные утилиты для просмотра онлайн-кинотеатров, видео на YouTube, торрент-видео и т.д. И почти все они сохраняют информацию о просмотрах пользователя и предлагают рекомендации, основываясь на опыте прошлых просмотров, что тоже требует авторизации. 

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

Implicit Flow. Позволяет получать на клиентскую часть Access токен и Refresh токен. Этот механизм можно быстро реализовать, но его безопасность далека от максимальной. 

Ситуацию можно описать так: мы отдаем на клиент наши токены и как бы говорим ему: «Храни наши токены, как хочешь, но мы будем ожидать, что ты будешь приходить к нам с конкретным токеном для получения информации». А потому нельзя быть уверенным в сохранности токенов. Такой flow стоит реализовывать, только если у вас защищенная сеть и нет утечек, когда злоумышленник попадает где-то на середине процессов.

Authorization Code Flow. Этот flow может быть альтернативой предыдущему, поскольку считается весьма безопасным. И хотя в нем клиентская часть знает Client ID и Client Secret, взаимодействие происходит уже с помощью Authorization-кода — это рандомно сгенерированный код. Обычно этот flow рекомендуют использовать для сервер-сайт приложений. Ярким примером является ASP.NET MVC приложение. Влезть в то, что генерируется сервером, сложно даже с какими-либо сторонними библиотеками.

Authorization Code Flow with Proof Key for Code Exchange (PKCE). Это усовершенствованный вариант прошлого flow. В нем происходит генерация еще двух рандомных кодов: Code Verifier и Code Challenge. На авторизацию мы идем с Code Challenge, после введения пользователем своих данных отдаем Authorization Code, за токеном мы идем с только что выданным Authorization Code и плюс с Code Verifier. В результате Identity-провайдер валидирует на основании трех кодов. 

Если злоумышленник вытащит один код из системы, он ничего не сможет сделать с ним — нужны все три кода. Примерами, где можно задействовать такой flow, являются Single Page Applications: Angular приложения, React JS приложения, и нативные приложения под Android/iOS.

Hybrid Flow. Этот гибридный flow объединяет Implicit Flow и Authorization Code. Разработчики попытались усложнить его, чтобы сделать чуточку безопаснее, но он фактически содержит в себе плюсы и минусы обоих «прародителей».

Плюсы и минусы трех популярных Identity-провайдеров

Далее рассмотрим готовые решения для использования в приложениях. Я бы выделила три: IdentityServer 4, Azure B2C и Keycloak.

IdentityServer 4

Этот провайдер поддерживает протоколы OpenID Connect и OAuth 2.0, а также внешние Identity-провайдеры. Можем подключить авторизацию с помощью Google, Facebook, Microsoft, Twitter, Instagram и т.д. Процесс установки и развертывания достаточно простой. Для этого надо создать приложение, установить Nuget-пакеты (IdentityServer4, IdentityServer4.EntityFramework, IdentityServer4.AspNetIdentity), а на клиентскую часть (если, например, MVC приложение в качестве клиента) — пакет IdentityModel. Он поможет нам получать «под капотом» информацию об Access токене и там же перенаправлять запросы, как нам нужно.

Преимуществами данного Identity-провайдера являются:

  • Гибкость настройки и возможность вносить кастомные валидаторы. Так как мы сами создаем приложение и туда инсталим Nuget-пакеты, то можем сами же переопределить, допустим, валидацию токена, если решили, что нужна еще одна дополнительная проверка.

  • Возможность создания UI. Мы можем создавать пользовательский интерфейс для страничек регистрации пользователей, логин-страниц, профиля пользователя и т.д. Существует реализация от создателей провайдера, но она подойдет не под любой случай. Поэтому сейчас IdentityServer 4 поставляется без пользовательского интерфейса, чтобы мы его не перекраивали, а просто сделали свой.

  • Поддержка flow. Он работает со всевозможными flow, которые мы уже рассматривали (Auth Code, Device Flow и т.д.).

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

  • Бесплатно для коммерческого использования. Не думаю, что стоит как-то особо комментировать этот пункт. Здесь и так понятно преимущество.

  • Подходит для CloudBase и On-Premise решений. Единственное, что стоит добавить к этому пункту: нам самим нужно позаботиться о том, как развернуть его в облаке.

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

Azure B2C

Этот Identity-провайдер поддерживает те же протоколы, что и IdentityServer 4, а также SAML и внешние провайдеры. По умолчанию у него предустановлены еще и пользовательские flow (Sign in, Sign up, Edit Profile, Password Reset), поддержка мультифакторной аутентификации и управление пользовательскими доступами.

Чтобы установить и настроить Azure B2C, потребуется подписка на Azure. Дальше мы создаем B2C Tenant ресурс, регистрируем API и клиентов с помощью App registrations. Чтобы все это подключить, понадобится один Nuget-пакет — Microsoft.Identity.Web, после чего у нас из кода все заведется.

На данном слайде можно оценить дизайн админки этого провайдера и функциональность App registrations. Для примера я создала одну API и два клиентских приложения. Для них формируется удобный список, где можно посмотреть разную информацию (как к ним подключиться, какие есть айдишники, скопы и т.д.). А еще можно добавить какую-то новую регистрацию.

Слева в меню мы видим меню Identity-провайдеров — здесь можно подключить внешние продукты. Есть меню пользователей и меню ролей с детальной статистикой. Мы можем увидеть, насколько часто юзеры логинятся в системе, увидеть их базовые цифры по взаимодействию с системой. И еще отмечу пункт User Flow. Я для примера выбрала парочку, которые созданы в несколько кликов — они предустановленные в Azure B2C. По итогу здесь нет никаких сложностей, когда нужно идти в какие-то конфиги, что-то настраивать и прописывать — с Azure B2C все легко и быстро.

У данного решения следующие плюсы:

  • Легкость конфигурации базовых user flows.

  • Cloud base решение.

  • User management «из коробки».

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

  • Простота старта. Для начала работы нужно совсем немного кода. Все настраивается в несколько кликов на Azure-портале, затем происходит подключение в самом приложении — и все работает уже на базовом flow.

  • Средний порог вхождения.

Несмотря на большое количество плюсов, есть у Azure B2C и минусы:

  • Платное решение. Кроме подписки на Azure, следует упомянуть еще один финансовый момент. Если у нас в течение месяца более 50 тысяч активных пользователей, то за это придется доплачивать. Мультифакторная аутентификация тоже платная и со своими сроками использования.

  • Сложность конфигурации flow. Для изменения даже базовых flow, например, добавления валидации или дополнительной информации, нужно создавать Custom Policy и много работать с конфигурационными XML и т.д.

  • Не подойдет для On-Premise решений. Azure B2C разворачивают только в Cloud, а такие решения обычно даже устанавливаются и там, где может не быть доступа к интернету в принципе.

Keycloak

Поддерживает все те же протоколы, что и Azure B2C: OpenID Connect, OAuth 2.0 и SAML — как и тех же Identity-провайдеров. У него также есть предустановленные пользовательские flow и — что тоже важно — LDAP и Active Directory. С их помощью можно интегрировать пользователей из других систем. Также отмечу предустановленное управление пользователями и их доступами.

Сам Keycloak написан на Java. Но так как сейчас в основном используется кроссплатформенность, и .NET Core является ярким представителем таких технологий, почему бы не попробовать интегрироваться с другим языком программирования? Keycloak как сервис предоставляется с помощью разных площадок (Kubernetes, Podman, Openshift, Docker). Лично я работала из Docker. Там нет никаких сложностей: запускаешь одну команду, чтобы загрузить нужные пакеты, а затем все установилось и запустилось.

Чтобы базово настроить flow авторизации, нужно выполнить следующий сценарий:

  1. Создать realm. Это точно такое же понятие, как и Tenant в Azure B2C, — то есть некая область или группа, в которые мы будем добавлять наше приложение в дальнейшем.

  2. Добавить клиентов. Ими выступают наши приложения, которые должны быть в этой системе.

  3. Добавить конфигурацию для этих приложений.

  4. Создать скопы.

  5. Создать роли.

Ниже вы можете видеть админку Keycloak. В первую очередь здесь приводится список клиентов в системе. Базово для аккаунта у нас есть уже клиент, он создается как часть сервиса. Но я также создала и зарегистрировала свое демо-приложение.

 

После перехода в меню приложения перед вами открывается множество возможностей для его конфигурации. Здесь представлены Client-скоупы, то есть стандартные скоупы (тот же e-mail, профайл и роли), но можно добавить и свои и подключить их на приложения.

В меню слева также собрано много полезной информации: мы можем смотреть и роли, и Identity-провайдеров, и пользователей, и сессии.

Плюсы Keycloak:

  • Гибкая настройка приложений и доступов к ним.

  • Готовая административная панель. Keycloak предлагает различные конфигурации в пользовательском интерфейсе. Чтобы настроить доступы к приложениям, нам не нужно копаться в конфигурационных файлах, а достаточно выбрать нужные пункты и сохранить их. Это сможет сделать даже администратор приложения.

  • Stand-alone приложение. Нам не надо заботиться, как его развернуть — все уже хостится само и полностью готово к работе.

  • Подходит для Cloud и On-Premise решений.

  • Бесплатное использование сервиса.

Среди минусов Keycloak:

  • Высокий порог вхождения. Продвинутому пользователю с ним будет проще. Из-за обилия настроек надо детально разбираться, как это все скорректировать.

  • Нет готовых официальных библиотек для .NET Core. Несмотря на это, мы можем из приложений интегрироваться с этим Identity-провайдером через тот же пакет Microsoft.AspNetCore.Authentication.JwtBearer. Он стандартно заложен в .NET Core.

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

  • Все сервисы поддерживают примерно одни и те же протоколы.

  • По стоимости проигрывает Azure B2C из-за оплаты подписки и пользовательской активности.

  • По части .NET Core проигрывает Keycloak. 

  • Насчет менеджмента есть интересный нюанс. В IdentityServer 4 мы можем все реализовать из кода сами (управление ролями, где их передавать и в каком виде). В Azure B2C весь роль-менеджмент проходит через Access Policy. Но роль-менеджмент в Azure-портале распространяется только на сам портал, а не на приложения, которые мы добавляем. А вот Keycloak содержит плюсы обоих Identity-провайдеров. Он позволяет использовать keycloak-роли, чтобы дать юзеру доступ к страничке о пользователе, которая хостится самим Keyclock. В то же время мы можем добавлять роли на ресурсы и пользователям. Таким образом настройка ролей и их добавление происходит более гибко, и в результате роль можно получить из того же токена.

  • По сложности настройки самый замысловатый Azure B2C. Если требуется какой-то базовый вариант, то все относительно нормально, на среднем уровне. Но чтобы что-то поменять, нужно сильно постараться.

В теме авторизации и аутентификации нельзя сказать: выбирайте только один flow, только один Identity-сервер или делайте только так. Более того, приведенные выше варианты — не единственные. Я советую сравнить разные готовые решения, взвесить их преимущества и недостатки и определить, что лучше всего подойдет именно в вашей ситуации.

Также делюсь полезными ссылками на официальную документацию перечисленных Identity-провайдеров:

Комментарии (5)


  1. Kostiantyn
    16.12.2021 14:14
    +5

    Сам Keycloak написан на Java. Но так как сейчас в основном используется кроссплатформенность, и .NET Core является ярким представителем таких технологий, почему бы не попробовать интегрироваться с другим языком программирования?

    Что за набор слов без смысла. Какая разница на чем написаны 2 разных приложения которые общаются между собой через редиректы пользовательского браузера и через HTTP?

    При чем тут кросплатформенность .NET? Какая вообще связть между кросплатформенностью и разными языками программирования?


  1. Kostiantyn
    16.12.2021 14:36
    +2

    Сам же OAuth 2.0 — это протокол авторизации, отвечающий за проверку доступов пользователя.

    Два ложных утверждения в одном предложении.

    Не читайте советских газет русскую википедию - это вредно.

    OAuth (Open Authorization[1][2]) is an open standard for access delegation - это не протокол, это стандарт (еще говорят что это фреймворк), и не авторизации а "делегорования доступа". При этом какой именно протокол и какая именно процедура аутентификации (не авторизации) пользователя будет использоваться нигде не регламентируется.

    И да, OAuth 2.0 никоим образом не "отвечает за проверку доступов пользователя" - этим каждое приложение занимается самостоятельно.


  1. medvedevia
    16.12.2021 17:58
    +1

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


  1. latonita
    17.12.2021 17:52

    Не ясно, откуда взялось "сравниваем лучшие identity провайдеры". Почему выбраны именно эти?)

    "Маловато!" Как говорил известный мульт герой

    Кто сказал, что они лучшие? Провайдеров много. Ясно, что выбрать сложно. Но как отправную точку можно взять, например, по-классике gartner и их magic quadrants. Ищем, открываем, и видим всех ключевых игроков. И тут уже было бы интересно сравнить их решения.

    Azure, aws, okta, auth0, ping,...


  1. aleks_raiden
    17.12.2021 18:49

    А еще есть ORY стек разных сервисов и полностью бесплатно ) https://www.ory.sh/