Это часть 2. Первую часть смотреть по ссылке.
Данная статья является второй из цикла по описанию особенностей построения приложений с использованием идей, описанных в книге «Искусство неизменяемой архитектуры: теория и практика управления данными в распределенных системах».
Описание создаваемого ТЕСТОВОГО / ТРЕНИРОВОЧНОГО приложения и базовые сокращения можно найти в начале первой части.
В рамках данной статьи будет описана задача реализации аутентификации внешних клиентов/сервисов с помощью сертификатов и идей «неизменяемой архитектуры».
Что такое аутентификация и ее отличие от авторизации можно уточнить по этой ссылке.
Что хочется от этого этапа/статьи?
Проверить, что работа с сертификатами это просто, удобно, универсально.
Постановка задачи
Мы создаем сервис по обработке запросов из внешних систем. Необходимо предусмотреть принятия запросов только от разрешенных систем. Запросы от не доверенных систем должны отбрасываться.
Решение должно быть простым для понимания, реализации и сопровождении.
Почему именно сертификаты
Причина выбора сертификатов для идей неизменяемой архитекторы связанны с идей неизменяемости. Один раз записанное/полученное/созданное никогда не должно меняться. Сертификаты позволяют создавать электронную цифровую подпись документов. Эти подписи можно сохранять вместе с «неизменяемыми записями» и в будущем проверять, что данные не были изменены.
Один раз созданный сертификат не изменяется, что согласуется с идеями, описанными в книге.
Технологии работы с сертификатами используются уже десятилетиями, они хорошо описаны и распространены. Библиотечные реализации доступны практически для всех языков программирования и хорошо стыкуются между разными языками программирования.
Архитектура аутентификации
Создание сертификатов
В книге «продвигается» идея, что сертификаты это просто. И это оказалось просто, но с нюансами.
На Windows компьютере удалось легко создать сертификат с помощью Putty. Но оказалось, что Putty создает сертификаты в формате, не поддерживаемом Java и Python. Однако из самого Putty удалось выгрузить сертификаты в формате OpenSSH. С сертификатами в формате OpenSSH Python библиотека cryptography заработала без проблем.
Но теперь Java не смогла работать с сертификатами OpenSSH, или я не смог ее настроить. Java может работать с сертификатами X.509. Однако удалось легко преобразовать OpenSSH сертификаты в формат, поддерживаемый Java. Данные шаги описаны в этом файле.
В результате есть закрытый ключ для подписи документов. И открытый ключ для проверки документов.
Сервис отправки запросов
Запросы к сервису обработки создаются в отдельном приложении, написанном на Python. Сервис сначала отправляет свой открытый ключ на сервер обработки данных. Это описано в следующем разделе.
При отправке запросов, каждый запрос подписывается закрытым ключом и цифровая подпись вставляется в заголовок.
Сразу же в заголовок вставляется открытый ключ для проверки подписи. Вот это является центральным местом этого этапа. Именно эта часть является, по сути, аутентификацией. Т. е. мы представляемся внешней системе с помощью открытого ключа, который можем сделать только мы на основании закрытого ключа. Отсюда следует, что система обработки запросов должна знать о нашем открытом ключе ДО того, как мы будем отправлять сообщения. В данном техническом решении это решено отправкой открытого ключа через REST сервис. В прод. решениях возможны разные способы. Однако главное удобство тут это то, что этот открытый ключ можно передавать по любым каналам связи. Это именно открытый ключ. Его невозможно подделать без закрытого ключа. Нет смысла в «секретных передачах» первого пароля.
Сервис обработки документов
Для аутентификации сообщений сервис проверки должен иметь открытый ключ. В рамках данного решения это сделано через REST сервис.
Каждый пришедший запрос, помимо тела запроса, имеет 2 заголовка:
И мы опять пришли к главному моменту. Мы проверяем пользователя по его открытому ключу. Т. е. мы должны иметь открытый ключ ДО того, как начнем проверять подпись этим открытым ключом, который нам пришлет пользователь еще раз.
Если пришедший открытый ключ уже есть в базе данных, то запрос становится проверенным/одобренным/взятым в работу.
Сразу возникает вопрос, как быть, если мы хотим прекратить доступ пользователя. Мы не можем удалить запись с его открытым ключом. Мы работаем в рамках «неизменяемой» архитектуры без update и delete. Для решения этой проблемы создана вторая сущность «отозванные сертификаты».
Каждый пришедший открытый ключ проверяется как на наличие в разрешенных открытых ключах, так и в отозванных сертификатах. Т. е. для отключения пользователя нужно добавить сертификат в список отозванных сертификатов. Благодаря поиску по индексированным полям все запросы выполняются быстро.
Итог: сертификаты позволили решить задачу просто и надежно?
В целом, да. В рамках данного этапа без каких то больших проблем удалось создать сертификаты в Putty. Подписать документ с помощью Python. Проверить подпись в Java. Решение сразу получилось простым, быстрым и с большим потенциалом на расширение.
Даже в текущей реализации это решение готов к использованию внутри корпоративных сетей. При доступе к данному решению из внешних сетей будет проблема, описанная в следующем абзаце.
Именно данное решение имеет ограничение по устойчивости к DDoS-атакам. Что бы проверить отправителя, необходимо прочитать от него сообщение полностью. Т. е. Множество «поддельных» отправителей смогут перегрузить систему. В данном конкретном случае, это принимаемое допущение. При выводе в прод. подобных решений есть множество способ решения этой проблемы. Обсуждение таких решений выходит за рамки этого цикла.
Результат данного этапа показал что подключать аутентификацию через сертификаты можно без создания сложной инфраструктуры управления сертификатами, просто создавая их вручную.
Выявилась проблема избыточного размера сообщений, т. к. в них постоянно дублируется сертификат, который УЖЕ имеет сервер. Но это «издержки» неизменяемой архитектуры. Однако сам открытый ключ имеет размер 451 байт.
Работа с сертификатами согласуется с неизменяемой архитектурой?
На 100%!
ссылка на оригинал статьи https://habr.com/ru/articles/1028300/