Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

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

Аутентификация на основе токенов в последние годы стала очень популярна из-за распространения одностраничных приложений, веб-API и интернета вещей. Чаще всего в качестве токенов используются Json Web Tokens (JWT). Хотя реализации бывают разные, но токены JWT превратились в стандарт де-факто.

При аутентификации на основе токенов состояния не отслеживаются. Мы не будем хранить информацию о пользователе на сервере или в сессии и даже не будем хранить JWT, использованные для клиентов.

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

Что дальше

В последнем разделе мы собрали собственный небольшой биллинг! Остается для полноты картины привернуть какой-нибудь WEB-интерфейс управления Базой Данных, добавить обязательное изменение пароля раз в месяц по крону. А если еще разориться сертификат и контроллер Wi-Fi точек доступа, то у вас в руках есть полноценная корпоративная беспроводная сеть.

Azure active directory b2c

У Microsoft есть сервис, который называется Azure Active Directory B2C. С помощью админов удалось настроить синхронизацию нашей AD с инстансом Azure AD и настроить вход через наш Active Directory Federation Services (ADFS).

Radius-сервер

Зайдем на наш компьютер с Linux и установим RADIUS-сервер. Я брал freeradius, и ставил я его на gentoo. К моему удивлению, в рунете нет материалов, относящихся к настройке Freeradius 2 для наших целей. Все статьи довольно стары, относятся к старым версиям этого програмного обеспечения.

root@localhost ~ # emerge -v freeradius


Все:) RADIUS-сервер уже может работать:) Вы можете проверить это так:

root@localhost ~ # radiusd -fX

Это debug-mode. Вся информация вываливается на консоль. Приступем к его настройке.

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

root@localhost ~ # cp -r /etc/raddb /etc/raddb.olg
root@localhost ~ # find /etc/raddb -type f -exec file {} ;  | grep 'text' | cut -d':' -f1 | xargs sed -i '/^ *t* *#/d;/^$/d'

Далее добавим клиента — точку доступа. Добавляем в файлик /etc/raddb/clients следующие строки:

root@localhost ~ # cat /etc/raddb/clients.conf | sed '/client test-wifi/,/}/!d'
client test-wifi {
        ipaddr = 192.168.0.1 #IP адрес точки, которая будет обращаться к радиусу
        secret = secret_key #Секретный ключик. Такой же надо будет поставить на Wi-Fi точке.
        require_message_authenticator = no  #Лучше так, с каким-то D-Linkом у меня не получилось иначе
}


Далее добавляем домен для пользователей. Сделаем дефолтовый.

root@localhost ~ # cat /etc/raddb/proxy.conf | sed '/realm DEFAULT/, /^}/!d'
realm DEFAULT {
        type = radius
        authhost = LOCAL
        acchost = LOCAL
}

Архитектору безопасности на заметку

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

При этом, мы не исключаем, что на этот же вопрос «Что из этого лучше подходит к моему приложению?» Архитектор ответит: «Кажется, что ничего не подходит. Придется делать свою модель с блэк-джеком». И в итоге, разработанная им модель окажется в данном списке в качестве новой «best practice» — смело делай pull requests в соответствующую шпаргалку от OWASP.

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

Архитектурные модели реализации аа

Мы провели декомпозицию функций АА (если собираешься стать архитектором безопасности приложений, то добавляй сложные слова и термины в свою коллекцию – возможно, они пригодятся на совещаниях) на основе характеристик типовых микросервисных приложений и определили следующий список подфункций безопасности (Рисунок 1): пограничная авторизация (edge-level authorization), авторизация на уровне сервиса (service-level authorization), пробрасывание идентификатора внешнего субъекта (external entity identity propagation), межсервисная аутентификация (service-to-service authentication). Затем мы рассмотрели основные электронные базы данных и библиотеки, а также стандарты безопасности и презентации на основных конференциях по безопасности с целью выявления существующих архитектурных схем.
image
Рисунок 1. Подфункции аутентификации и авторизации в системах на базе микросервисов

Разберем основные модели и их схемы.

В простом сценарии авторизация может происходить только на пограничном уровне (при помощи шлюза API). Шлюз API можно использовать в качестве центра авторизации для всех последующих микросервисов, исключая необходимость обеспечения аутентификации и контроля доступа для каждого отдельного микросервиса.

Однако авторизация на пограничном уровне имеет следующие недостатки:

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

Уверен, эта картинка знакома всем:

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

Некоторые путают термины «аутентификация» и «авторизация». Это разные вещи.

Ещё тут?

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

Базовая настройка

В этой статье нас будут интересовать в первую очередь WPA2-EAP/TLS способ авторизации.

Практически все современные точки доступа Wi-Fi стоимостью больше 3 тыс. рублей поддерживают нужную нам технологию. Клиентские устройства поддерживают и подавно.

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

Беспарольная аутентификация

Первой реакцией на термин «беспарольная аутентификация» может быть «Как аутентифицировать кого-то без пароля? Разве такое возможно?»

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

Беспарольная аутентификация — это способ конфигурирования процедуры входа и аутентификации пользователей без ввода паролей. Идея такая:

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

Есть похожий метод, при котором вместо одноразовой ссылки по SMS отправляется код или одноразовый пароль. Но тогда придётся объединить ваше приложение с SMS-сервисом вроде twilio (и сервис не бесплатен). Код или одноразовый пароль тоже можно отправлять по почте.

И ещё один, менее (пока) популярный (и доступный только на устройствах Apple) метод беспарольной аутентификации: использовать Touch ID для аутентификации по отпечаткам пальцев. Подробнее о технологии.

Если вы пользуетесь Slack, то уже могли столкнуться с беспарольной аутентификацией.

Выбор способа аутентификации

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

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

Двухфакторная аутентификация (2fa)

Двухфакторная аутентификация (2FA) улучшает безопасность доступа за счёт использования двух методов (также называемых факторами) проверки личности пользователя. Это разновидность многофакторной аутентификации. Наверное, вам не приходило в голову, но в банкоматах вы проходите двухфакторную аутентификацию: на вашей банковской карте должна быть записана правильная информация, и в дополнение к этому вы вводите PIN.

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

Децентрализованный шаблон

В этом шаблоне команда разработчиков реализует PDP и PEP непосредственно на уровне кода микросервиса (рис. 3). Все правила контроля доступа, а также атрибуты, необходимые для реализации этого правила, определяются и хранятся в каждом микросервисе (шаг 1). Когда микросервис получает (шаг 2) запрос на доступ вместе с некоторыми метаданными авторизации (например, контекст конечного пользователя), микросервис анализирует его (шаг 3) для того, чтобы сгенерировать решение политики контроля доступа, а затем реализует (enforce) авторизацию (шаг 4).
image
Рисунок 3. Высокоуровневая архитектура децентрализованного шаблона

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

Соответственно, данная модель несет в себе следующие ограничения:

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

Для чего они нужны?

IdToken — содержит учетные данные пользователяAccessToken — для авторизации на APIRefreshToken — для обновления AccessToken

Вопрос на засыпку: зачем необходимы два токена Access и Refresh?

Сам JWT-IdToken токен выглядит так:
Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Из этого токена мобильное приложение получает информацию об аутентифицированном пользователе. Соответственно, IdToken мы используем для отрисовки ФИО пользователя и его аватарки.

AccessToken мы прикрепляем к header запросов:

Для аутентификации web-клиента также достаточно просто выполнить интерактивный вход через IdenitityProvider. Ниже пример из официальной документации, как это прикрутить к Angular4-приложению.

Как видно из примеров, никто не ушёл обиженным — реализация для клиентов получается простой и понятной.

Для полного счастья нам не хватало аутентификации пользователей через нашу локальную Active Directory.

Для настройки синхронизации между Auth0 и локальной Active Directory, Auth0 предоставляет powershell-скрипт.

Когда мы уже обрадовались, что всё отлично работает, и пошли к админам с просьбой настроить синхронизацию между нашим AD и Auth0, то получили отказ. Ребята сказали, что максимум, куда они готовы лить наши данные, — это Azure. Также на решение повлияло то, что у нас уже использовалась подписка Office 365 и часть учёток уже была залита в Azure.

Окей, сказали мы.

Корпоративный wifi на ubnt с порталом и доменной аутентификацией

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

Схема тестового стенда выглядит так:

Подробности под катом.

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

Первая задача

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

В Profiles добавляем наш Radius-сервер, указав общий Secret. Точка должна быть добавлена как Radius Client на сервере. Если точек много, можно настроить nat, чтобы все точки виделись на сервере с одним IP.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Добавляем нужные SSID на контроллере.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр
Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Особенность решения заключается в том, что Radius-сервер должен применять разные политики аутентификации для этих SSID. Разделение по политикам можно сделать на основании поля Called-Station-ID, который передается в запросе аутентификации и представляет собой MAC точки и SSID.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Для этого создаем политику для Private vlan, которая проверяет, является ли пользователь членом доменной группы WIFI_PL_Private.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

В условиях указываем регулярное выражение для Caller Station ID, позволяющее проверять SSID со всех точек в сети .*:PL_Private, а также проверку членства в группе.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

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

Третья политика разрешает доступ к сети PL_Public для всех пользователей домена.

Вторая задача — гостевой портал для одноразовых паролей. Эта задача решается средствами самого контроллера UniFi.

Для сети PL_Guest определяем, что она является открытой и гостевой.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Во вкладке Guest Portal включаем Hotspot-аутентификацию, при желании кастомизируем стартовую страницу портала.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

В настройках Hotspot включаем аутентификацию по ваучерам.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Нажав на ссылку Go to hotspot manager, генерируем ваучеры.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

При попытке подключения к гостевой сети с телефона, видим приглашение ввести код ваучера:

После подключения видим в менеджере хотспота статистику.

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

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

Благодарю за внимание 🙂

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

Существует два общих способа реализации межсервисной аутентификации:

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

Настройка клиентов

Пробежимся по настройке основных пользовательских устройств. У наших сотрудников есть клиенты, работающие на Android, iOS и Windows 7. Оговоримся сразу: так как мы используем самосозданные сертификаты, то нам нужно несколько раз вносить всевозможные исключения и подтверждать действия. Если бы мы пользовали купленные сертификаты, возможно, все было бы проще.

Настройка точки доступа

Главное, чтоб точка поддерживала нужный способ аутентификации. Оно может называться по разному в разных устройствах: WPA-EAP, WPA2 Enterprise и т.д. Во всяком случае выбираем аутентификацию, устанавливаем IP-адрес и порт RADIUS-сервера и ключ, который мы вводили в clients.conf при настройке Freeradius.

Приведу картинку с настроенной точки Ubiquiti. Помечено галкой то, что нужно менять.

image

Немного про проект

Мы в 2ГИС делаем крутой и точный справочник компаний. Для обеспечения качества и актуальности данных в 2ГИС есть несколько внутренних систем. Одна из них называется YouLa — нет, не та, где публикуют объявления. Наша YouLa поддерживает процесс выверки данных на местности.

Часть системы — мобильное приложение, с которым ходят пешеходники. Пешеходники — специалисты, которые обходят весь город. Карта разбита на разные участки для проверки.

Посмотрите, как выглядит территориальное деление Московской области. Разные цвета на карте обозначают разные назначения территорий.

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

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

На нашем новом бекенде мы хотим знать, что за пользователь к нам пришёл.

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

— надежность и безопасность,— аутентификация по разным источникам,— аутентификация нескольких типов клиентов Web, Mobile, API.

Немного теории

Когда-то давно инженерами IEEE был придуман стандарт 802.1x. Этот стандарт отвечает за возможность авторизации пользователя сразу при подключении к среде передачи данных. Иными словами, если для соединения, например, PPPoE, вы подключаетесь к среде(коммутатору), и уже можете осуществлять передачу данных, авторизация нужна для выхода в интернет.

В случае же 802.1x вы не сможете делать ничего, пока не авторизуетесь. Само конечное устройство вас не допустит. Аналогичная ситуация с Wi-Fi точками доступа. Решение же о допуске вас принимается на внешнем сервере авторизации. Это может быть RADIUS, TACACS, TACACS и т.д.

Облачные решения

Первой платформой, которую мы решили попробовать, был Auth0. Платформа очень крутая и для разработчика, и для администратора. В ней есть подробная документация, красивый и понятный Web UI для настройки всех параметров. В наше Java/Kotlin-приложение и на бекенд аутентификация была прикручена за пару часов.

Основные плюсы, которые мы отметили при работе с платформой Auth0:

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

Для того, чтобы реализовать поддержку JWT аутентификации в бекенде, достаточно написать всего несколько строчек (этот код для разных платформ будет отличаться только параметрами Authority и Audience), в некоторых случаях потребуется ещё указать сертификаты для проверки подписи токенов:

Для того, чтобы прикрутить аутентификацию к мобилке — ещё несколько строчек:

Как видно из примера, после аутентификации к нам приходит два токена ещё один (RefreshToken) не показан в коде.

Обо всём ещё разок

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

Auth0 — отличный провайдер, очень дружественно настроенный к разработчикам. Приятное API, нет проблем с интеграцией. Если у вас нет каких-то административных барьеров, то рекомендую к использованию 🙂

Azure Active Directory B2C — хорош для Enterprise. Скорее всего, удастся договориться с админами и юристами. Пока ещё довольно сырой, поэтому приходится писать конфиги в xml. Ещё одна особенность платформы — для администрирования инстанса B2C в России требуется учётка того, кто привязал карту к аккаунту. Это неудобно, пока идёт отладка и тестирование.

Firebase Auth — самый лайтовый вариант. Подойдёт, если не требуется сложных сценариев входа и достаточно просто иметь аутентификацию. Из минусов — довольно аскетичная админ-панель и небольшой перечень дефолтных источников аутентификации.

Что ещё можно добавить?

Использование стандартов, в частности OpenId Connect, позволило нам:

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

Всем безопасного бекенда и лёгкой аутентификации на фронте 🙂

Общая схема сети

Для наглядного понимания приведем общую схему работы нашей будущей схемы:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Переезд на google firebase auth

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

Так как на клиенте мы абстрагировались от конкретного провайдера, то переехали на Google Firebase Auth за час.

Из доработок на бекенде потребовалось добавить код для скачивания сертификатов Google, которыми Firebase подписывает токены авторизации.

Сейчас, когда мы запустились в продакшн на Firebase, проблему с синхронизацией данных в Azure AD удалось решить. Поэтому в перспективе мы возможно вернёмся на Azure.

Реализация сервера авторизации oauth с помощью сервера авторизации spring

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Сервер авторизации в OAuth предназначен для выдачи маркера доступа, который позволяет клиентскому приложению использовать этот маркер доступа для запроса ресурса, который ему нужно получить. Сервер ресурсов будет подтверждать этот маркер доступа с помощью сервера авторизации каждый раз, когда клиентское приложение запрашивает ресурс, чтобы определить, следует ли разрешить клиентскому приложению доступ к этому ресурсу. Вы можете использовать множество различных открытых источников, таких как Keycloak, Spring Security OAuth (устаревший), или же новый проект Spring под названием Spring Authorization Server для реализации этого сервера авторизации. В этом руководстве я покажу вам, как использовать сервер авторизации Spring (Spring Authorization Server) для реализации сервера авторизации OAuth (OAuth Authorization Server)!

Сначала я создам новый проект Spring Boot с Web Starter, Security Starter:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

и сервер авторизации Spring:

<dependency>
    <groupId>org.springframework.security.experimental</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
    <version>0.1.2</version>
</dependency>

для примера.

Результат:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Конфигурация сервера авторизации

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

По умолчанию сервер авторизации Spring  поддерживает класс OAuth2AuthorizationServerConfiguration с конфигурациями по умолчанию для сервера авторизации. Если взглянуть на код этого класса, то можно увидеть, что он определяет метод applyDefaultSecurity(), который инициализирует объект OAuth2AuthorizationServerConfigurer с целью применения конфигураций по умолчанию, которые определяет этот класс OAuth2AuthorizationServerConfigurer:

public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =
            new OAuth2AuthorizationServerConfigurer<>();
    RequestMatcher endpointsMatcher = authorizationServerConfigurer
            .getEndpointsMatcher();

    http
        .requestMatcher(endpointsMatcher)
        .authorizeRequests(authorizeRequests ->
            authorizeRequests.anyRequest().authenticated()
        )
        .csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
        .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
        .apply(authorizationServerConfigurer);
}

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

Класс OAuth2AuthorizationServerConfiguration также определяет бин (bean) для класса SecurityFilterChain, который вызывает метод applyDefaultSecurity() для регистрации этих конфигураций по умолчанию в Spring Security сервера авторизации.

Вы можете импортировать этот класс OAuth2AuthorizationServerConfiguration с помощью аннотации Spring @Import, чтобы использовать эти конфигурации по умолчанию:

package com.huongdanjava.springauthorizationserver;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;

@Configuration
@Import(OAuth2AuthorizationServerConfiguration.class)
public class AuthorizationServerConfiguration {

}

или если вы хотите добавить что-то из пользовательского кода, то давайте объявим бин для класса SecurityFilterChain и вызовем метод applyDefaultSecurity() следующим образом:

package com.huongdanjava.springauthorizationserver;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class AuthorizationServerConfiguration {

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

        return http.formLogin(Customizer.withDefaults()).build();
    }

}

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

При использовании сервера авторизации нам важно определить веб-ключ JSON для проверки информации в маркере доступа, который пользователь запросил у сервера ресурсов, выданном сервером авторизации. Для завершения настройки этого сервера авторизации требуется бин JwtDecoder с объектом класса JWKSource. Мы можем определить бины для этих объектов следующим образом:

@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
    return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}

@Bean
public JWKSource<SecurityContext> jwkSource() throws NoSuchAlgorithmException {
    RSAKey rsaKey = generateRsa();
    JWKSet jwkSet = new JWKSet(rsaKey);

    return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
}

private static RSAKey generateRsa() throws NoSuchAlgorithmException {
    KeyPair keyPair = generateRsaKey();
    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

    return new RSAKey.Builder(publicKey)
        .privateKey(privateKey)
        .keyID(UUID.randomUUID().toString())
        .build();
}

private static KeyPair generateRsaKey() throws NoSuchAlgorithmException {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(2048);

    return keyPairGenerator.generateKeyPair();
}

Конфигурация Spring Security

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

Мы можем определить SecurityFilterChain следующим образом:

package com.huongdanjava.springauthorizationserver;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SpringSecurityConfiguration {

    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authorizeRequests ->
                authorizeRequests.anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults());

        return http.build();
    }

}

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

Регистрация клиента на сервере авторизации

Сервер авторизации Spring использует класс RegisteredClient для объявления информации клиента, зарегистрированного на сервере авторизации, и реализует интерфейс RegisteredClientRepository для хранения информации всех этих клиентов.

Мы можем объявить информацию о клиенте, используя память или соответствующую базу данных:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Для простоты я буду использовать память следующим образом:

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("huongdanjava")
        .clientSecret("{noop}123456")
        .clientAuthenticationMethod(ClientAuthenticationMethod.POST)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .redirectUri("https://oidcdebugger.com/debug")
        .scope(OidcScopes.OPENID)
        .build();

    return new InMemoryRegisteredClientRepository(registeredClient);
}

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

Что такое идентификатор клиента, объяснять не нужно! По поводу типа гранта авторизации, следует отметить, что сервер авторизации Spring поддерживает все типы грантов OAuth 2.

Секрет клиента зависит от типа клиента, который мы хотим определить, если наш клиент конфиденциальный, см. также Типы клиентов в OAuth 2.0, то секрет клиента обязателен. Здесь вам нужно объявить, как зашифровать клиентский секрет с помощью PasswordEncoder, если вы не хотите шифровать его в целях тестирования, то можно использовать NoOpPasswordEncoder, объявив “{noop}” в начале клиентского секрета, как я сделал выше. Помните, что это применяется только в тестовых целях!

Если клиент является конфиденциальным, нам также понадобится Метод Client Authentication для определения маркера доступа.

В зависимости от типа гранта клиента, который вы определяете, есть и другая необходимая информация, которую нам нужно объявить. Например, в моем случае я определяю клиента с типом разрешения authorization_code, поэтому мне нужно определить redirect_uri. Здесь я буду использовать инструмент https://oidcdebugger.com/ для получения кода авторизации, поэтому я определяю redirect_uri со значением https://oidcdebugger.com/debug, как это можно видеть в примере.

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

Регистрация пользователя на сервере авторизации

Для регистрации пользователя на сервере авторизации используется память со следующим объявлением:

@Bean
public UserDetailsService users() {
    UserDetails user = User.withDefaultPasswordEncoder()
        .username("admin")
        .password("password")
        .roles("ADMIN")
        .build();

    return new InMemoryUserDetailsManager(user);
}

Итак, на данном этапе мы завершили базовую конфигурацию для Authorization Server.

Чтобы проверить результаты, я воспользуюсь инструментом https://oidcdebugger.com/, как упоминалось выше, со следующим объявлением:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Нажмите кнопку Send request (Отправить запрос) на этой странице, после чего вы откроете страницу входа на сервер авторизации, которая будет выглядеть следующим образом:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Войдите в систему с информацией, которую мы объявили выше, и увидите следующие результаты:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Используя этот код авторизации вместе с секретом клиента, который мы объявили, вы можете получить маркер доступа для этого клиента следующим образом:

Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Материал подготовлен в рамках курса «Разработчик на Spring Framework». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.

Терминология

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

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

Также существует довольно большое количество способов соедининея конечного устройства к серверу авторизации (PEAP, TLS, TTLS…). Я не буду их здесь описывать.

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

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

На этапах разработки и внедрения программного продукта необходимо решить множество проблем безопасности. Основополагающими требованиями, над которыми ломает голову aрхитектор безопасности (Application Security Architect – роль в крупной продуктовой компании, которая еще не избавляет от технических задач Security Engineer’a, но которая уже добавляет высокоуровневые проблемы, связанные с архитектурой и процессами) и которые должны быть решены на этапе проектирования, являются аутентификация и авторизация (для краткости, АА).

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

Исследование проводится с учетом трех ключевых вопросов:

В ходе исследования мы провели обзор основных электронных библиотек научных статей, мы также просмотрели стандарты безопасности, презентации на крупных конференциях по безопасности и локальных тематических митапах (привет, OWASP Moscow Meetup).

Итогом стали следующие результаты:

Централизованная модель со встроенной точкой принятия решения

В этой модели правила контроля доступа определяются централизованно, но хранятся и оцениваются на уровне микросервисов (рисунок 5). Правила контроля доступа определяются с помощью PAP (шаг 1) и доставляются во встроенную PDP вместе с атрибутами субъектов и объектов доступа, которые необходимы для использования этих правил (шаг 2). Когда субъект вызывает микросервиса (шаг 3), код микросервиса вызывает PDP, а PDP генерирует решение политики контроля доступа, оценивая входной запрос по правилам и атрибутам контроля доступа (шаг 4). На основе решения PDP микросервис применяет авторизацию (шаг 5).
image
Рисунок 5 Высокоуровневая архитектура централизованной модели со встроенной PDP

PDP код в этом случае может быть реализован как встроенная библиотека микросервиса или «sidecar-прокси». Sidecar обрабатывают коммуникации между сервисами, производят мониторинг и устраняют проблемы безопасности, то есть все, что может быть абстрагировано от отдельных сервисов, подробнее можно почитать тут.

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

Основное отличие от “централизованного шаблона с единой точкой принятия решения” с подходом к кэшированию заключается в том, что решения по авторизации не хранятся на стороне микросервиса, вместо этого на стороне микросервиса хранится актуальная политика авторизации.

В выступлении “How Netflix Is Solving Authorization Across Their Cloud” представлен практический пример применения шаблона “Централизованную модель со встроенной PDP” для реализации авторизации на уровне микросервисов (рисунок 6):

Преимущества этих шаблонов такие же, как и для “Централизованных шаблонов с одним PDP”. Кроме того, шаблон не сильно влияет на задержки в обслуживании сетевых запросов из-за встраивания PDP на уровне микросервисов.

Существует несколько проблем, которые необходимо учитывать при применении этой модели:

  • этот шаблон опирается на ручные или полуручные правила политики доступа, разработанные командой безопасности, которые могут быть подвержены ошибкам — во избежание уязвимостей конфигурации необходимо применять методы тестирования и верификации безопасности;
  • архитекторы безопасности приложений должны комбинировать его с другими шаблонами (например, авторизация на пограничном уровне), чтобы избежать наличия единой точки принятия решений и обеспечить соблюдение принципа “эшелонированной обороны”;
  • может случиться так, что некоторые специфические для бизнеса правила контроля доступа не могут быть реализованы таким образом — архитекторы безопасности приложений должны комбинировать этот шаблон с “Децентрализованным шаблоном”;
  • архитекторы безопасности приложений должны выбрать подход, как получать обновления политик авторизации из централизованных PAP (например, опрос PAP или механизм публикации-подписки);
  • команда разработчиков должна безопасно использовать сторонние компоненты авторизации и описывать политику контроля доступа, используя некий формальный язык, который в некоторых случаях может быть накладным — “Децентрализованный шаблон” может быть достаточным для реализации некоторой простой политики контроля доступа.

Централизованный доступ к эцп и прочим ключам электронной защиты с помощью аппаратных usb over ip

Хочу поделиться нашим годичным опытом при поиске решения для организации централизованного и упорядоченного доступа к ключам электронной защиты в нашей организации (ключи для доступа к площадкам для торгов, банковские, ключи защиты программного обеспечения и т.д.). В связи с наличием у нас филиалов, территориально весьма разнесенных друг от друга, и наличием в каждом из них по нескольку ключей электронной защиты — постоянно возникает необходимость в них, но в разных филиалах. После очередной суеты с потерянным ключом, руководство поставило задачу — решить эту проблему и собрать ВСЕ USB устройства защиты в одном месте, и обеспечить с ними работу не зависимо от места расположения сотрудника.

Итак, нам необходимо собрать в одном офисе все имеющиеся в нашей компании ключи банк клиентов, лицензий 1с (hasp), рутокены, ESMART Token USB 64K, и т.д. для последующей эксплуатации на удаленных физических и виртуальных машинах Hyper-V. Количество usb устройств – 50-60 и точно, что это не предел. Расположение серверов виртуализации вне офиса (датацентр). Расположение всех USB устройств в офисе.

Изучили существующие технологии централизованного доступа к USB устройствам и решили остановиться на технологии USB поверх IP (USB over IP). Оказывается, очень многие организации пользуются именно этим решением. На рынке есть как аппаратные средства проброса USB по IP, так и программные, но они нас не устраивали. По сему, далее речь пойдет только о выборе аппаратных USB over IP и в первую очередь о нашем выборе. Устройства из Китая (безымянные) мы тоже исключили из рассмотрения.

Наиболее описываемым на просторах интернета аппаратным решением USB over IP являются устройства производства США и Германии. Для детального изучения приобрели большой стоечный вариант этого USB over IP, рассчитанный на 14 портов USB, с возможностью монтажа в 19 дюймовую стойку и немецкий USB over IP, рассчитанный на 20 портов USB, так же с возможностью монтажа в 19 дюймовую стойку. К сожалению на большее количество портов устройств USB over IP у этих производителей не было.

Первое устройство весьма дорогое и интересное (в интернете полно обзоров), но есть очень большой минус — нет никаких систем авторизации для подключения USB устройств. Любой, кто установит приложение для подключения USB, получает доступ ко всем ключам. В дополнение, как показала практика, USB устройство «esmart token est64u-r1» непригодно для использования с устройством и, забегая вперед, с «немецким» на ОС Win7 – при подключении к нему перманентный BSOD.

Второе устройство USB over IP нам показалось интереснее. Устройство имеет большой набор настроек, связанных с сетевыми функциями. Интерфейс USB over IP логично разбит на разделы, так что первоначальная настройка была достаточно простой и быстрой. Но, как упоминалось ранее, возникли проблемы с подключением ряда ключей.

Изучая дальше аппаратные USB over IP натолкнулись на отечественных производителей. Модельный ряд включает 16, 32, 48 и 64 портовую версию с возможностью крепления в 19 дюймовую стойку. Описываемый производителем функционал был даже побогаче, чем у предыдущих приобретенных USB over IP. Изначально понравилось, что отечественный управляемый USB over IP концентратор обеспечивает двухступенчатую защиту USB устройств при совместном использовании USB по сети:

  1. Удаленное физическое включение и выключение USB устройств;
  2. Авторизацию для подключения USB устройств по логину, паролю и IP адресу.
  3. Авторизацию для подключения USB портов по логину, паролю и IP адресу.
  4. Журналирование как всех включений и подключений USB устройств клиентами, так и таких попыток (не правильный ввод пароля и т.д. ).
  5. Шифрование трафика (с чем в принципе было неплохо и на немецкой модели).
  6. Дополнительно подходило, что устройство, хоть и не дешевое, но в разы дешевле купленных ранее (особенно существенной становится разница при пересчете на порт, мы рассматривали 64-х портовый USB over IP).

Решили уточнить у производителя, как же обстоит дело с поддержкой двух типов смарт токенов, имеющих проблемы подключения ранее. Нам сообщили, что не дают 100% гарантии поддержки абсолютно всех USB устройств, но пока еще не нашли ни одного устройства, с которым бы были проблемы. Нас такой ответ мало устроил и мы предложили производителю передать токены для тестирования (благо пересылка транспортной компанией стоила всего 150р, а старых токенов у нас достаточно). Через 4 дня после отправки ключей нам сообщили данные для подключения и мы к ним чудесно подключились с Windows 7, 10 и Windows Server 2008. Все работало нормально, мы без проблем подключали свои токены и имели возможность с ними работать.

Приобрели управляемый USB over IP концентратор на 64 порта USB. Подключили с 18 компьютеров в разных филиалах все 64 порта (32 ключа и остальное – флешки, жесткие диски и 3 USB камеры) – все устройства работали без проблем. В целом устройством остались довольны.

Наименования и производителей USB over IP устройств не привожу (дабы не было рекламой), их достаточно просто найти в интернете.

Централизованный шаблон с единой точкой принятия решения

В этой модели правила контроля доступа определяются, хранятся и оцениваются централизованно (рисунок 4). Правила контроля доступа определяются с помощью PAP (шаг 1) и доставляются в централизованную PDP вместе с атрибутами субъектов и объектов доступа, которые необходимы для использования этих правил (шаг 2).

Когда субъект вызывает микросервис (шаг 3), код микросервиса вызывает централизованный PDP через сетевой вызов, а PDP генерирует решение политики контроля доступа, оценивая входной запрос по правилам и атрибутам контроля доступа (шаг 4). На основе решения PDP микросервис реализует авторизацию (шаг 5).

image
Рисунок 4. Высокоуровневая архитектура централизованного шаблона с единой PDP

Некоторыми преимуществами этой схемы являются:

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

Для определения правил контроля доступа команда разработчиков и DevOps-инженеров должна использовать язык или нотацию. Примером может служить язык разметки Extensible Access Control Markup Language (XACML) и Next Generation Access Control (NGAC), который является стандартом для реализации описания правил политики.

Этот шаблон плохо влияет на время обслуживания запросов из-за дополнительных сетевых вызовов PDP; использование кэширования решений политики авторизации на стороне микросервиса позволяет уменьшить сетевые задержки.

Следует отметить, что PDP должен работать в режиме высокой доступности из-за возможных проблем с отказоустойчивостью. Архитекторы безопасности приложений должны комбинировать его с другими шаблонами (например, авторизация на уровне шлюза API), чтобы избежать наличия единой точки принятия решений и обеспечить соблюдение принципа “эшелонированной обороны”.

Чем хорош jwt и стандарт openid connect в enterprise?

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

Схема работы всех компонентов выглядит вот так:
Централизованный доступ к ЭЦП и прочим ключам электронной защиты с помощью аппаратных USB over IP / Хабр

Похожее:  GitHub - arut/nginx-rtmp-module: NGINX-based Media Streaming Server

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

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