Реализация SSO через SAML с примером / Хабр

Что такое аутентификация?

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

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

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

Основные поля


Кратко остановимся на том, какие есть стандартные полях в токене и зачем они нужны:

Основные понятия

Прежде чем начать разбираться с решениями и подходами следует определиться в терминах и последовательности процессов:

Federated identity glossary

The concept of a centralized or linked electronic identity is known as federated identity. Federated identity systems handle several concerns:

Forms authentication

Реализация SSO через SAML с примером / Хабр

How does sso work?

Authentication with SSO relies on a trust relationship between domains (websites). With single sign-on, this is what happens when you try to log in to an app or website:

Jwt токен — состав

Заголовок

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

Тип токена хранится в ключе «typ». Ключ «typ» игнорируется в JWT. Если ключ «typ» присутствует, его значение должно быть JWT, чтобы указать, что этот объект является JSON Web Token.

Второй ключ «alg» определяет алгоритм, используемый для шифрования токена. По умолчанию он должен быть установлен в HS256. Заголовок кодируется в base64.

{ “alg”: “HS256”, “typ”: “JWT”}Payload (содержимое) — в полезной нагрузке хранится любая информация, которую нужно проверить. Каждый ключ в полезной нагрузке известен как «заявление». К примеру, в приложение можно войти только по приглашению (закрытое промо).

Когда мы хотим пригласить кого-то поучаствовать, мы отправляем ему письмо с приглашением. Важно проверить, что адрес электронной почты принадлежит человеку, который принимает приглашение, поэтому мы включим этот адрес в полезную нагрузку, для этого сохраним его в ключе «e-mail»

Jwt токен и его преимущества

JWT (JSON Web Token) — открытый стандарт (

Saml sso flow

The diagram below illustrates the single sign-on flow for service provider-initiated SSO, i.e. when an application triggers SSO.

Sso strategy

SAML is an XML-based open-standard data format for exchanging authentication and authorization data between parties, in particular, between an identity provider and a service provider.

OAuth is an open protocol to allow secure authorization in a simple and standard method from web, mobile, and desktop applications.

Token authentication

Реализация SSO через SAML с примером / Хабр

Следующее поколение способов аутентификации представляет Token Based Authentication, который обычно применяется при построении систем Single sign-on (SSO). При его использовании запрашиваемый сервис делегирует функцию проверки достоверности сведений о пользователе другому сервису. Т. е. провайдер услуг доверяет выдачу необходимых для доступа токенов собственно токен-провайдеру (Identity provider).

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

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

На следующей схеме дополнительно отражены те этапы взаимодействия, в которых пользователь принимает непосредственное участие. Этот момент и является недостатком подобной схемы — нам всегда нужен пользователь, чтобы получить доступ к ресурсу.
Реализация SSO через SAML с примером / Хабр

Xpath-инъекции

Еще одна интересная уязвимость — это XPath-инъекция. Рассмотрим, как происходит проверка подписи SAML Response. Обычно код, осуществляющий проверку подписи, ищет элемент <ds:Signature> и из дочернего элемента <ds:Reference> извлекает атрибут URI.

Если приложение не производит проверку значения URI на наличие XPath-конструкций при составлении выражения, то такая реализация уязвима к XPath-инъекциям.

Свежая XPath-инъекция найдена в конце 2022 года в ruby-saml. Ниже представлена строка из xml_security.rb, которая стала причиной инъекции:

hashed_element = document.at_xpath("//*[@ID='#{uri[1..-1]}']")

В случае с Ruby эта уязвимость приводит к RCE. Во всем виновата особенность реализации XPath в Ruby, которая выполняет shell команды внутри обратных кавычек. Если приложение использует ruby-saml, то для определения наличия уязвимости необходимо в атрибут URI элемента подставить следующее значение:

Xxe повсюду

SAML-сообщения представляют собой XML. Это означает, что тестируемое приложение потенциально подвержено уязвимостям, связанным с парсингом XML. Сюда можно отнести уязвимости XML External Entities (XXE), Server-Side Request Forgery (SSRF) и XML Entity Expansion (XEE, в массах более известна как Billion Laughs attack).

Эти уязвимости очень распространены, когда речь идет о парсинге XML. На страницах Хакера про эти уязвимости не раз писали, поэтому я не буду подробно на них останавливаться. Только порекомендую хорошую «методичку» по данным уязвимостям. Эти уязвимости работают, несмотря на то что SAML-сообщение подписано, так как проверка подписи происходит уже после парсинга XML.

Первым делом при тестировании безопасности SAML SSO нужно перехватить сообщение Response и заменить его на следующее:

Арсенал для тестирования saml sso

На данном этапе у тебя есть тестируемое приложение с работоспособным SAML SSO. Разберемся, какие инструменты использовать для тестирования безопасности.

Конечно, в первую очередь утилиты с сайта, которые ранее упоминались:

  • раздел CODE/DECODE позволит тебе закодировать или декодировать сообщения SAML;
  • раздел SIGN позволит тебе подписать SAML-сообщения, используя секретный ключ;
  • раздел VALIDATE позволит тебе проверить подпись у SAML-сообщения;
  • раздел ENCRYPT/DECRYPT позволит тебе зашифровать или расшифровать SAML-сообщения, для расшифровки понадобится секретный ключ;
  • раздел EXAMPLES содержит примеры различных SAML-сообщений.

Если ты занимаешься веб-безопасностью, то, скорее всего, в твоем хакерском арсенале есть Burp Suite. Я представлю два плагина, которые предназначены для тестирования SAML. Ты можешь использовать эти плагины даже с бесплатной версией Burp Suite.

Первый плагин — это SAML Editor, написан на Python. Для того чтобы он заработал, придется установить Jython standalone и указать в настройках Burp Extender путь к Jython. Плагин очень простой, он добавляет дополнительную табу с именем SAML, которая позволяет редактировать SAML-сообщения на лету (рис. 12). Больше он ничего не умеет, его удобно использовать, чтобы быстро отредактировать сообщение.

Рис. 12. Плагин SAML Editor
Рис. 12. Плагин SAML Editor

Атаки xsw

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

Предположим, что IdP подписывает только assertion и не подписывает само сообщение. Наше приложение принимает Response, проверяет подпись assertion и аутентифицирует пользователя. SAML Response показан на рис. 15. При проверке подписи приложение ищет при помощи XPath элемент , у которого атрибут ID равен значению abc.

Рис. 15. Оригинальный SAML Response
Рис. 15. Оригинальный SAML Response

Теперь попробуем модифицировать оригинальный SAML Response. Добавим в сообщение элемент <samlp:Extensions>, который содержит из оригинального сообщения. По спецификации SAML элемент <samlp:Extensions> является необязательным и может содержать внутри себя любые элементы.

Также в сообщение вместо оригинального элемента <saml:Assertion ID = “abc”> мы вставляем свой элемент <saml:Assertion ID = “evil”>. В качестве подписи для <saml:Assertion ID = “evil”> мы используем подпись для <saml:Assertion ID = “abc”>. После манипуляций SAML Response выглядит, как показано на рис. 16.

При проверке подписи приложение использует элемент <saml:Assertion ID = “abc”>, который является дочерним для . Проверка подписи успешно проходит. Но для аутентификации пользователя приложение использует элемент <saml:Assertion ID = “evil”>. Это и есть XSW-атака.

Рис. 16. Модифицированный SAML Response
Рис. 16. Модифицированный SAML Response

Атаки на зашифрованные assertions

SAML позволяет шифровать assertions, если assertion содержит конфиденциальную информацию. SAML не позволяет шифровать отдельные атрибуты, поэтому assertion шифруется целиком. Пример SAML Response с зашифрованным assertion доступен здесь.

В сообщение Response вместо элемента <saml:Assertion> присутствует элемент <saml:EncryptedAssertion>, зашифрованный и закодированный в Base64 assertion, а также симметричный ключ шифрования, оба находятся внутри элементов <xenc:CipherData>.

Для шифрования симметричного ключа шифрования используется алгоритм RSAES-PKCS1-v1_5. Для шифрования данных обычно используется блочный шифр (AES) в режиме CBC.

Если при расшифровывании assertion приложение выступает в качестве Оракула (Oracle), то после расшифровки оно сообщает о том, что padding неверный или расшифрованное сообщение не является валидным XML. Приложение может сообщать это в виде явного сообщения об ошибке либо в виде различного тайминга.

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

Юрай Соморовски (Juraj Somorovsky) опубликовал работу, посвященную атакам на XML-шифрование. В работе описан алгоритм, который позволит атакующему расшифровать при выполнении двух условий: приложение уязвимо к ошибкам проверки подписи и приложение выступает в качестве Оракула.

Также в 2022 году Юрай Соморовски на конференции Black Hat EU представил утилиту WS-Attacker, которая реализует алгоритм из его работы про атаки на XML-шифрование. Ссылка на презентацию тут. Я же опишу основные идеи алгоритма.

Процесс расшифровывания assertion выглядит, как это показано на рис. 17. Предположим, что для шифрования используется AES-CBC (размер блока 16 байт). Расшифрованный i-й блок Pi получается следующим образом:

Pi = Ci-1 ⨁ D(k,Ci) = Ci-1 ⨁ x

Ci-1 обозначает i-1 блок шифротекста, Ci — соответственно, i блок шифротекста. Операция расшифровывания с использованием алгоритма AES обозначена как D(k,Ci), результат этой операции обозначен как x.

Рис. 17. Операция расшифровывания assertion при помощи блочного шифра в режиме СВС
Рис. 17. Операция расшифровывания assertion при помощи блочного шифра в режиме СВС

Рассмотрим, каким образом осуществляется паддинг при XML-шифровании. Допустим, у нас есть следующий XML — <ABC/>. XML кодируется в UTF-8. То есть мы получаем следующий закодированный XML (6 байт) — 0x3c 0x41 0x42 0x43 0x2f 0x3e.

Блок шифрования для AES составляет 16 байт. Поэтому мы должны использовать 10 байт паддинга — 0x3c 0x41 0x42 0x43 0x2f 0x3e 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x0A (0x?? означает любое значение байта). Последний байт — это длина паддинга (равен 0x0A в нашем случае).

Предположим, что мы хотим расшифровать блок шифротекста Ci (без знания ключа шифрования). Мы оставляем только блоки шифротекста с номерами от 0 до i: C0, …, Ci. Далее мы модифицируем блок шифротекста Ci-1 особым образом и отправляем SAML Response приложению для расшифровки.

Наша задача — сделать такую модификацию Ci-1, чтобы при расшифровке на стороне приложения получился валидный XML и паддинг был равен одному байту (последний байт расшифрованного блока равен 0x01). Модифицированный блок Ci-1 обозначен как C~i-1.

Рис. 18. Находим модифицированное значение C(i-1)
Рис. 18. Находим модифицированное значение Ci-1

Если мы нашли C~i-1, то мы сможем вычислить последний байт Pi (или Pi[16]) расшифрованного блока (открытого текста). Сначала мы вычисляем x[16] как

x[16] = 0x01 ⨁ C~i-1[16]

И затем

Pi[16] = 0x01 ⨁ C~i-1[16] ⨁ Ci-1[16]

На следующем шаге мы получаем расшифрованное значение для остальных байтов (с 1-го по 15-й). Допустим, мы хотим вычислить Pi[3]. Для этого мы добавляем (операция XOR) C~i-1[3] различные значения (назовем их «маски») и смотрим ответ приложения — возвращается ли ошибка вследствие невалидного XML или нет.

Атаки через сжатие сообщений saml

IdP может сжимать сообщение SAML Response и затем его преобразовывать в Base64. Поэтому тестируемое приложение может ожидать, что сообщение придется распаковывать.

Используя Python, мы можем получить закодированный SAML Response (Deflate Base64) следующим образом:

Балансировка нагрузки

Балансировщик нагрузки является единой точкой входа в keycloak и должен поддерживать sticky sessions.

Взгляд сверху

Picture7

Обычно в системах встречаются разные компоненты: пользователи, работающие через браузер, пользователи, взаимодействующие с сервером через мобильные приложения, и просто серверные приложения, нуждающиеся в принадлежащих вам данных, хранящихся на других серверах, доступ к которым осуществляется через Web API.

Запрос на аутентификацию


Authentication/Token Request — процесс запроса аутентификации.

В зависимости от того какие области (scopes) запрошены, сервис выдачи токенов вернет:

  1. Только Identity Token, если запрошены только Identity scopes.
  2. Identity Token и Access Token, если запрошены также и Resources scopes.
  3. Access Token и Refresh Token, если запрошeн Offline Access.

Более подробно про процесс аутентификации можно прочесть в разделе «

Идентификационный брокер keycloak

Keycloak

— это решение для управления идентификацией и доступом с открытым исходным кодом, предназначенное для использования в ИС где могут использоваться паттерны микросервисной архитектуры.

Keycloak предлагает такие функции, как единый вход (SSO), брокерская идентификация и социальный вход в систему, федерация пользователей, клиентские адаптеры, консоль администратора и консоль управления учетными записями.

Базовый функционал, поддерживаемый в Keycloak:

Ищем уязвимости в saml sso

Самая интересная часть статьи — это какие уязвимости в реализации SAML SSO ты можешь найти на стороне приложения. Поехали.

Клиент


Client — устройство или программа (браузер, приложение), которым требуется либо токен для аутентификации пользователя, либо токен для доступа к какому-то ресурсу (подразумевается, что данный ресурс «знаком» с тем конкретным «

» у которого клиент запрашивает токен для доступа).

Настраиваем saml sso в приложении

После того как мы разобрались с теорией, приступим к настройке SAML SSO для тестируемого приложения. У нас есть развернутое приложение, теперь нам нужен SAML IdP (провайдер). Я предпочитаю OneLogin, он популярен, и многие приложения его поддерживают.

Регистрируем бесплатный девелоперский аккаунт. Идем в APPS → Company Apps, затем нажимаем кнопку Add Apps. В строке поиска необходимо набрать SAML Test Connector, как показано на рис. 3. Далее выбираем SAML Test Connector (IdP w/attr).

Рис. 3. Создание тестового коннектора
Рис. 3. Создание тестового коннектора

Задаем имя для коннектора и нажимаем кнопку Save.

На стороне нашего приложения идем в настройки SAML IdP (рис. 4). Нам нужно скопировать значения полей Issuer, ACS URL, Logout URL. Эти три параметра нам генерирует приложение, и они используются для настройки коннектора на стороне IdP.

Рис. 4. Настройки SAML IdP приложения
Рис. 4. Настройки SAML IdP приложения

Параметры, которые сгенерировало приложение, необходимо перенести в настройки коннектора, как показано на рис. 5. На этом все, настройка коннектора завершена!

Рис. 5. Настройка коннектора
Рис. 5. Настройка коннектора

Переходим на вкладку SSO. Копируем значения X.509 certificate, Issuer URL, SAML Endpoint и SLO Endpoint из настроек коннектора в настройки нашего приложения (рис. 6).

Рис. 6. Параметры SSO
Рис. 6. Параметры SSO

Область (scope)


Scope — идентификатор ресурса, к которому клиент хочет получить доступ. Список scope посылается в адрес

в составе

По умолчанию все клиенты имеют возможность запрашивать любые области, но это можно (и нужно) ограничивать в конфигурации сервиса выдачи токенов.

Scopes бывают двух видов:

  1. Identity scopes — это запрос информации о пользователе. Его имя, профиль, пол, фотография, адрес электронной почты и т. д.
  2. Resource scopes — имена внешних ресурсо (Web APIs), к которым клиент хочет получить доступ.

Построение архитектуры отказоустойчивого кластера keycloak

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

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

Для работы в режиме Active/Active и Active/Passive кластера требуется обеспечивать консистентность данных в реляционной базе данных — оба узла базы данных должны синхронно реплицироваться между различными геораспределенными ЦОД.

Самый простой пример отказоустойчивой инсталяции.

Какие преимущества дает использование единого кластера:

Преобразования и цифровая подпись

Стандарт цифровой подписи в XML предусматривает различные трансформации (преобразования) XML-документа перед его подписью. У элемента <ds:Signature> есть дочерний элемент <ds:Transforms>, который содержит несколько элементов <ds:Transform>. Каждый элемент <ds:Transform> определяет одно преобразование.

Возможны следующие преобразования:

SAML IdP при формировании подписи проводит последовательность трансформаций. Проверяющая подпись сторона — наше приложение должно осуществить ту же самую последовательность преобразований в процессе проверки валидности подписи.

Прозрачная авторизация на rds с помощью sso (single sign-on) | windows для системных администраторов

Single Sign-On (SSO — технология единого входа) это технология, позволяющая уже аутентифицированному (вошедшему в систему) пользователю получать доступ к другим сервисам без повторной аутентификации. Применительно к технологии терминальных серверов Remote Desktop Services, SSO позволяет избавить пользователя, выполнившего вход на доменном компьютере, от многократного ввода имени и пароля своей учетной записи в окне RDP клиента при подключении к RDS серверам или запуске опубликованных приложений RemoteApp.

В этой статье мы опишем особенности настройки прозрачной авторизации (Single Sign-On) пользователей на серверах RDS под управлением Windows Server 2022 и 2022 R2.

Требования к окружению:

Процедура настройки Single Sign-On состоит из следующих этапов:

  • Необходимо выпустить и назначить SSL сертификат на серверах RD Gateway, RD Web и RD Connection Broker;
  • Включить Web SSO на сервере RDWeb;
  • Настроить групповую политику делегирования учетных данных;
  • Через GPO добавить отпечаток сертификата в доверенные издатели .rdp.

Итак, в первую очередь нужно выпустить и назначить SSL сертификат. В EKU (Enhanced Key Usage) сертификата должно обязательно присутствовать идентификатор Server Authentication. Мы опускаем процедуру получения сертификата, т.к. это она выходит за рамки статьи (можно сгенерировать самоподписанный SSL сертификат, но его придется добавлять в доверенные на всех клиентах через GPO).

SSL сертификат привязывается в свойствах RDS Deployment в подразделе Certificates.

Установка SSL сертификатов на RDSДалее на всех серверах c ролью Web Access для каталога IIS RDWeb нужно включать “Windows Authentication” и отключить анонимную проверку подлинности (Anonymous Authentication).

RD WEB - включаем аутентфикацию Windows После сохранения изменений, IIS нужно перезапустить:
iisreset /noforce

Если используется шлюз RD Gateway, убедитесь, что он не используется для подключения внутренних клиентов (должна стоять галка Bypass RD Gateway server for local address).

Bypass RD Gateway server for local address

Следующий этап – настройка политики делегирования учетных данных. Создайте новую доменную GPO и привяжите ее к OU с пользователями (компьютерами), которым нужно разрешить SSO доступ на RDS сервера. Если вы хотите разрешить SSO для всех пользователей домена, допустимо редактировать Default Domain Policy.

Эта политика находится в разделе GPO Computer Configuration -> Administrative Templates -> System -> Credential Delegation -> Allow delegation defaults credential (Конфигурация компьютера -> Административные шаблоны -> Передача учетных данных -> Разрешить передачу учетных данных, установленных по-умолчанию). Политика разрешает определенным серверам доступ к учетным данным пользователей Windows.

Далее, чтобы избежать появления окна с предупреждением о надежности издателя удаленного приложения, нужно с помощью GPO на клиентских компьютерах добавить адрес сервера с ролью Connection Broker в доверенную зону с помощью политики «Список назначений зоны безопасности для веб-сайтов» (по аналогии со статьей Как убрать предупреждение системы безопасности при открытии файла в Windows):

User/Computer Configuration -> Administrative Tools -> Windows Components -> Internet Explorer -> Internet Control Panel -> Security Page-> Site to Zone assignment list (Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Internet Explorer -> Панель управления браузером -> Вкладка безопасность)

Укажите FQDN имя сервера RDCB и зону 2 (Trusted sites).

Добавить сайт в доверенныеДалее нужно включить политику Logon options (Параметры входа) в разделе User/Computer Configuration -> Administrative Tools -> Windows Components -> Internet Explorer -> Internet Control Panel -> Security -> Trusted Sites Zone (Административные шаблоны -> Компоненты Windows -> Internet Explorer -> Панель управления браузером -> Вкладка безопасность -> Зона надежных сайтов) и в выпадающем списке выбрать ‘Automatic logon with current username and password‘ (Автоматический вход в сеть с текущим именем пользователя и паролем).

После обновления политик на клиенте, при попытке запустить RemoteApp приложение, запрос пароля не появится, но появится окно с предупреждением о доверии к издателю данной программы RemoteApp:

Do you trust the publisher of this RemoteApp program?

вы доверяете издателю данного RemoteApp

Чтобы это сообщение не выводилось каждый раз при подключении пользователя, вам нужно получить отпечаток SSL сертификата (certificate thumbprint) RD Connection Broker и добавить его в список доверенных издателей rdp. Для этого на сервере RDS Connection Broker выполните команду PowerShell:

Get-Childitem CERT:LocalMachineMy

Получить отпечаток сертификатаСкопируйте значение отпечатка сертификата и добавьте его в список отпечатков политики Specify SHA1 thumbprints of certificates representing RDP publishers (Указать отпечатки SHA1 сертификатов, представляющих доверенных издателей RDP) в секции Computer Configuration -> Administrative Templates -> Windows Components -> Windows Desktop Services -> Remote Desktop Connection Client (Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Клиент подключения к удаленному рабочему столу).

Specify SHA1 thumbprints of certificates representing RDP publishers

На этом настройка SSO закончена, и после применения политик, пользователь должен подключатся к ферме RDS по протоколу RDP без повторного ввода пароля.

Теперь при запуске клиента mstsc.exe (Remote Desktop Connection), если вы укажете имя RDS сервера, в поле UserName автоматически подставится имя пользователя в формате ([email protected]).

Your Windows logon credentials will be used to connect.

RDP - ващи данные для входа в Windows будут использоваться для rdp подключения

Чтобы использовать RD Gateway с SSO нужно для пользователей включить политику Set RD Gateway Authentication Method (User Configuration -> Policies -> Administrative Templates -> Windows Components -> Remote Desktop Services -> RD Gateway) и установить ее значение на Use Locally Logged-On Credentials.

Active X компонент MsRdpClientShell

Для использования Web SSO на RD Web Access, обратите внимание, что рекомендуется использовать Internet Explorer с включенным Active X компонентом MsRdpClientShell (Microsoft Remote Desktop Services Web Access Control).

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

Picture9

Разбираемся детально ху из ху

В данный момент на слуху следующие протоколы:

  1. OpenID — для проверки учетных данных пользователя (identification & authentication).
  2. OAuth — про то, чтобы получать доступ к чему-то.
  3. OpenID Connect — и про и то, и про другое одновременно.

Распределенный кеш (infinspan)

Для корректной работы кластера требуется дополнительная синхронизация следующих типов кеша с использованием JBoss Data Grid:

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

Action tokens — используются для сценариев, когда пользователю необходимо подтвердить действие асинхронно (по электронной почте). Например, во время потока forget password кэш actionTokens Infinispan используется для отслеживания метаданных о связанных маркерах действий, которые уже использовались, поэтому его нельзя использовать повторно.

Caching and invalidation of persistent data – используется для кэширования постоянных данных, чтобы избежать лишних запросов к базе данных. Когда какой-либо сервер Keycloak обновляет данные, все остальные серверы Keycloak во всех центрах обработки данных должны знать об этом.

Work — используется только для отправки сообщений о недействительности между узлами кластера и центрами обработки данных.

Реализация sso через saml с примером

Введение

Доброго времени суток, дорогой читатель. Я уже давно хотел написать статью на хабре и вот наконец-то этот момент настал. Из последних тем, которыми я занимался и о которых мне есть что рассказать — это была реализация SSO для одного сервиса. Хочу здесь сразу уточнить, что в принципе SSO через Facebook и Google уже было в сервисе до моего прихода. Моей же задачей было реализовать его через протокол SAML.

SSO (Single Sign-On), — технология единого входа пользователей, благодаря которой владея одной лишь учетной записью пользователь может посещать множество различных сервисов.

SAML — это популярный XML-протокол для реализации SSO. Как правило большие организации (enterprise) используют именно его, как проверенный и надежный вариант.

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

Технические детали

На момент написания статьи, последняя версия стандарта — SAML 2.0. Базируется стандарт на XML, а значит и все требования стандартов w3c к XML так же применимы и к нему, не забывайте про это. Так, например в момент реализации, я словил одну ошибку. В момент создания AuthnRequest я генерировал уникальный строковый идентификатор для атрибута ID, так вот по требованиям он не должен начинаться с цифры, а у меня периодически так было.

В аутентификации через SAML SSO участвует три стороны:

Сама схема взаимодействия представлена на рисунке ниже

Из нее получается два основных кейса взаимодействия, причем один содержит в себе другой.

Вариант 1. Пользователь обращается к сервису. Сервис формирует сообщение AuthnRequest, кладет в параметр SAMLRequest и делает редирект через браузер к провайдеру на Login URL, где происходит аутентификация, затем провайдер формирует сообщение Response, кладет его в параметр SamlResponse и редиректит обратно в сервис на ACS URL.

Вариант 2. Пользователь уже аутентифицирован и находится в личном кабинете провайдера, откуда он может перейти в сервис, кликая по его ярлыку. В данной ситуации провайдер сразу формирует сообщение Response, кладет его в параметр SamlResponse и направляет в сервис на ACS URL.

ACS URL (Assertion Consumer Service URL) — урл на стороне нашего приложения, который принимает запросы с параметром SamlResponse, обрабатывает его (выдергивает сообщение Response, проверяет подпись по сертификату, различные правила) и если все хорошо, то создает рабочую сессию пользователя в приложении.

IdP Login URL — урл на стороне провайдера, который принимает запросы с параметром SAMLRequest и так же выполняет должную валидацию этого параметра, и если все хорошо, то отправляет на форму аутентификации.

В качестве IdP провайдeра может выступать один из онлайн-сервисов, таких как OneLogin, LastPass, Okta и другие. Также можно развернуть свой IdP с помощью Shibboleth или поднять AD.

Настройки

Все параметры для этого взаимодействия должны настраиваться и храниться на обеих сторонах (IdP, SP), то есть должны быть выстроены доверительные отношения.

SP должен хранить у себя сертификат, который выдаст IdP, а также Saml Login URL, на который будет отправлять SAMLRequest.

IdP обязательно должен хранить у себя для размещаемого приложения ACS URL

image

… должен сформировать сертификат, выбрать алгоритм шифрования, предоставить Saml Login URL для сервиса…

image

… должен настроить (если необходимо) атрибуты пользователя или еще какие-то кастомные поля для конкретного сервиса. Сервис с провайдером должны также договориться о формате Subject NameID. Это по сути идентификатор пользователя, информация о котором будет передана в сообщениях. В нашем случае это email.

image

Помимо ручной настройки, SP и IdP должны уметь генерировать файл метаданных, содержащий все необходимые параметры для “коллеги”, чтобы тот мог и загрузить и выставить настройки сам. У нас такой задачи не было.

В дополнение еще скажу, что помимо SSO, провайдеры опционально предоставляют еще и услугу SLO (Single Logout) — механизм, который предполагает выход сразу из всех сервисов одновременно. Возможны также две точки входа:

Для этого надо поддержать на стороне сервиса обработку запросов SP SLO URL и отправку запросов к IdP SLO URL. Такой задачи у меня также не было.

Исследования

И так, задача поставлена, с теорией ознакомился, пора и делать начать. Первым делом ознакомился со списком имеющихся библиотек. Backend нашего сервиса написан на Java, искал библиотеки именно для него. Наиболее полный список продуктов, связанных с SAML можно увидеть тут. Выбрал для себя наиболее очевидные решения: Okta SAML Toolkit for Java, SpringSecurity SAML, OIOSAML 2.0 Toolkit, lastpass/saml-sdk-java, OneLogin 2.0, OneLogin 1.1.2, OpenSAML 2.0. Далее нужно было определить критерии, по которым будет выбрано то или иное решение. Так была составлена следующая таблица.

Если честно, исходный код предложенных решений просто ужаснул — известные провайдеры решили написать свои высокоуровневые прикладные библиотеки (получилось не очень), большая часть (слава богу) решений была основана на низкоуровневой библиотеке работы с SAML OpenSaml 2.0. Учитывая, что все эти библиотеки так или иначе пришлось бы править затачивая под потребности нашей логики и встраивать в наш основной код со всеми юнит-тестами было решено также использовать уже имеющийся базис в виде OpenSaml 2.0 и на нем писать нашу высокоуровневую логику. Возможно, если бы у нас был Spring, я бы стал использовать SpringSecurity SAML, но его у нас нет.

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

image

Итого, решение выбрано, поведение определено.

Реализация

В качестве IdP для тестирования я выбрал, как можно увидеть по скринам выше, OneLogin. Он предоставляет бесплатный девeлоперский аккаунт, с ним проще всего было настроить тестовое приложение, а также он содержит набор утилит для работы с SAML, которые смогут облегчить Вам работу. Если не надо никакого полноценного конфигурируемого IdP, то можно использовать простую эту утилиту или ее аналог от Okta. Ими я тоже пользовался.

Сначала я написал свое тестовое локальное приложение чтобы обкатать в принципе эту технологию, его исходники я Вам и продемонстрирую. Затем уже перенес это решение на промышленную кодобазу. Логика приложения простая и применимая для любого сервиса. Приложение предлагает пользователю ввести email, если для этого домена не настроено SSO SAML, то приложение просит ввести внутренний пароль юзера (в примере ругается, что юзер не может SSO). Если же настроено, то смотрим на какой IdP настроен данный домен, формируем сообщение и перенаправляем запрос туда. После успешной аутентификации получаем сформированное сообщение на наш ACS URL от IdP, из сообщения берем email, берем сертификат для данного домена и проводим валидацию сообщения. В случае успешной проверки берем атрибуты из сообщения FirstName, LastName. Если пользователь уже существует меняем ему значения этих атрибутов в нашем сервисе. Если пользователя еще нет, то создаем его.

Это так называемый Just-in-Time Provisioning. Эта самая простая реализация провижининга (синхронизация) пользователей, которую можно сделать. Минусом такой синхронизации можно назвать отсрочку выполнения до следующего входа пользователя. Плюс невозможность удаления пользователя на стороне сервиса при удалении юзера из IdP. Чтобы полноценно запустить провижининг в сервисе необходимо реализовать стандарт SCIM, но этого я еще не делал — возможно это будет следующая история.

Надеюсь, эта статья была полезна для Вас.

Сервера приложений

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

На этом первая часть – теоретическая — закончена. В следующих циклах статей будут разобраны примеры интеграций с различными идентификационными провайдерами и примеры настроек.

Сервис выдачи токенов

Open ID Connect Provider — важнейший объект всей конструкции централизованного сервиса аутентификации, он также может называться Security Token Service, Identity Provider authorization server и т. д. Различные источники называют его по-разному, но по смыслу это сервис, который выдает токены клиентам.

Основные функции:

Типовые сценарии авторизации с использование oauth2 в keycloak

Authorization Code Flow

Токен доступа

Access Token — информация, что конкретному пользователю разрешается делать. Клиент запрашивает Access Token и затем использует его для доступа к ресурсам (Web APIs). Access Token содержит информацию о клиенте и пользователе, если она присутствует. Важно понимать, что есть такие типы авторизации, при которых пользователь в процессе непосредственно не участвует (подробнее об этом в следующей части)

Токен личности

Identity Token — подтверждение аутентификации. Этот токен содержит минимальный набор информации о пользователе.

Токен обновления

Refresh Token — токен, по которому STS вернет новый Access Token. В зависимости от режима работы, Refresh Token может быть многоразовым и одноразовым. В случае с одноразовым токеном, при запросе нового Access Token будет также сформирован готовый Refresh Token, который следует использовать при повторном обновлении. Очевидно, что одноразовые токены более безопасны.

Более подробно о составе токенов в разделе «структура токена».

Формат

Picture10

Заключение

Итак, ты получил представление о том, каким уязвимостям подвержены приложения с поддержкой SAML SSO. Ты узнал, каким образом настроить SSO с помощью SAML в приложении, какие инструменты использовать для тестирования безопасности SAML SSO.

Надеюсь, что теперь, если ты столкнешься с SAML SSO, будешь знать, куда копать. Успешного багхантинга!

Заключение первой части

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

Stay tuned.

Спойлер второй части

Минимальная реализация интеграция Identity Server в ваше приложение выглядит так:

public void Configuration(IAppBuilder app)
{
    var factory = new IdentityServerServiceFactory();
    factory.UseInMemoryClients(Clients.Get())
           .UseInMemoryScopes(Scopes.Get())
           .UseInMemoryUsers(Users.Get());

    var options = new IdentityServerOptions
    {
        SiteName = Constants.IdentityServerName,
        SigningCertificate = Certificate.Get(),
        Factory = factory,
    };

    app.UseIdentityServer(options);
}

Минимальная реализация интеграции веб-клиента с Identity Server:

public void Configuration(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = "Cookies"
    });

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        ClientId = Constants.ClientName,
        Authority = Constants.IdentityServerAddress,
        RedirectUri = Constants.ClientReturnUrl,
        ResponseType = "id_token",
        Scope = "openid email",
        SignInAsAuthenticationType = "Cookies",
    });
}

Минимальная реализация интеграции веб-API с Identity Server:

public void Configuration(IAppBuilder app)
{
    app.UseIdentityServerBearerTokenAuthentication(
        new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = Constants.IdentityServerAddress,
            RequiredScopes = new[] { "write" },
            ValidationMode = ValidationMode.Local,

            // credentials for the introspection endpoint
            ClientId = "write",
            ClientSecret = "secret"
        });

    app.UseWebApi(WebApiConfig.Register());
}

Похожее:  Working with SOAP based Web Service using Python | by AYUSHI SHARMA | Medium

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *