@evgeniykhist
Java Solution Architect

Как в микросервисах ограничивать доступ на уровне сущностей?

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

Каков наилучший способ реализовать это в микросервисах?

№1

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

№2

Создать специализированный микросервис для управления правами доступа ко всем объектам? Этот сервис будет вызываться другими микросервисами для проверки прав доступа для каждого объекта и фильтрации объектов перед возвратом результатов. Централизованное хранение и управление разрешениями является преимуществом, но микросервис должен будет вызвать «Permission Service» для каждого объекта, чтобы проверить права доступа, что может отрицательно повлиять на производительность. И разработчикам по-прежнему придется интегрировать проверки доступа в свои сервисы, что оставляет пространство для ошибки.

№3

Обеспечить контроль доступа на уровне API Gateway или Service Mesh. Можно придумать реализацию, которая будет автоматически фильтровать ответы всех служб. Но в случае, когда микросервис возвращает список, проверка прав доступа должен быть проведена для каждого объекта. По-прежнему потенциальная проблема с производительностью.

Пример

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

Результаты испытаний должны быть доступны только для:

  • пациента
  • врача
  • лаборатории


Лечащий врач может отправить пациента к другому специалисту. Новый врач также должен иметь доступ к результатам анализов. Таким образом, доступ может предоставляться динамически.

Каждый объект (например, результаты анализов, рентгеновское изображение) имеет набор правил, каким пользователям и группам разрешен доступ к нему.

Представьте себе, что существует микросервис «TestResultsService», обрабатывающий результаты анализов. Должен ли он отвечать за контроль доступа, управлять разрешениями и т.д.? Или управление правами доступа должно быть выделено в отдельный микросервис?

Система здравоохранения может также обрабатывать визиты к врачу. Информация о визите пациента к врачу должна быть доступна:

  • пациенту
  • врачу
  • ресепшионисту


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

Легко представить еще больше примеров, когда требуется управление доступом на уровне сущности.
  • Вопрос задан
  • 2843 просмотра
Решения вопроса 1
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
1. Создайте общее "дерево" зависимостей сущностей (work-flow).
2. Создайте роли для разных объектов (пользователей/групп/сервисов и т.д.).
3. Создайте битовые ACL-"маски" для конкретных объектов и привяжите их к нужным узлам "дерева".
4. Если нужно управлять доступами динамически: создайте доп."маски" доступов (service override ACL) и меняйте их конкретным сервисом.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
chupasaurus
@chupasaurus
Сею рефлекторное, злое, временное
AAA (Authorization, Authentication, Accounting, не имею в виду семейство протоколов, а саму идею) - это всегда отдельная тяжелая служба, потому что высокая связность и зависимость других служб не входят в парадигму микросервисов.
Лучше всего себя показывает такой подход (AWS IAM, фейсбучная проверка доступа, тысячи их): отдельный сервис для работы с ACL, непосредственно контроль доступа - на стороне микросервисов.
Формат ACL можете честно стырить у IAM: на каждый тип объектов - базовые active,owner,read,edit и присущие этому типу, все ID объектов в одном формате и биективны, записи по каждому виду доступа в двух видах: Permission - ID (например для владельца) и Permission - ID List.
Непосредственно контроль доступа - на стороне микросервисов без выноса в отдельные сущности. Доступ проверяется по ID объекта, инициализирующего действие, по надобности ещё проверяются и его группы.
На вашем примере: PatientTHX1138, врач DoctorMengl создает карту о визите Case23523 и анализы Test991235-991237. У каждого анализа есть права на чтение/изменение всех его данных (для пациента/его лечащих врачей) или только даты приёма, кабинета и проводящего врача (для ресепшна). Дело передаётся отдельной функцией путем замены в ACL владельца, предыдущий врач в зависимости от причины передачи либо лишается доступа (увольнение/отстранение), либо получает доступ на чтение в обычном случае передачи, либо получает доступ на запись в случае передачи внутри группы врачей. Аналогичная ситуация с разным уровнем доступа для врачей и ресепшна у самого визита и пациента (ресепшну вряд ли надо знать, какого размера камень в почках).
Ответ написан
Комментировать
@AlexHell
Я сам не реализовывал микросервисы, но недавно на хабре читал про JSON Web Token да вот на википедии даж https://ru.wikipedia.org/wiki/JSON_Web_Token
и вот еще про Access + Refresh Token https://habrahabr.ru/company/Voximplant/blog/323160/
смысл в том есть служба аутентификации и выдачи токена, она своим секретным ключем шифрует токены (1 access или 2 access + refresh) и выдает клиенту, в простом случае я бы записал туда ID юзера и его Роль (админ, обычный юзер), и передавал с клиента на каждый микросервис, который его проверяет:
-- в 1м из вариантов расшифровывает секретным ключем - тогда каждый микросервис знает о секрет ключе основном которым подписывал сервис аутентификации
-- во 2м варианте юзаем ассимметричное шифрование т.е секрет знает толькосервис аутентификации а другие его беспроблемно расшифруют (меньше подвергаемся утечке ключа если много сервисов и не всем мы доверяем)

во всех случаях сервис к которому обращается клиент не должен обращаться к сервису аутентификации что не замедляет скорость работы.
Ответ написан
Комментировать
@evgeniykhist Автор вопроса
Java Solution Architect
Я пришел к следующему решению.

  1. Использовать ACL модель безопасности. Каждый объект в системе имеет связанный с ним набор разрешений (permissions). Разрешения определяют, кто и какие действия могут выполнять над объектом.
  2. Микросервисы отвечают за авторизацию на уровне сущности и фильтрацию объектов в ответах на основе разрешений этих объектов.
  3. Служба централизованного контроля доступа (Access Control Service) отвечает за создание, обновление и удаление разрешений для всех объектов в системе. База данных Access Control Service является основным хранилищем разрешений объектов.
  4. Разрешения, хранящиеся в базах данных микросервисов, которые синхронизируются с базой данных Access Control Service с использованием event-carried state transfer. Каждый раз, когда изменяются разрешения, событие отправляется брокеру сообщений (message broker). Микросервисы могут подписываться на эти события для синхронизации разрешений.
  5. API Gateway может использоваться как дополнительный уровень защиты. API Gateway может напрямую обращаться к Access Control Service (RPC) для проверки разрешений объектов ответа или загрузки недавно отозванных разрешений.
5a461ac4b5fd0699968243.png

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

  1. Требуется возможность уникальной идентификации каждого объекта в системе (например, UUID).
  2. Синхронизация разрешений в микросервисах eventual consistent. В случае разделения сети (partition) между брокером сообщений и микросервисом, разрешения не будут синхронизироваться. Это может быть проблемой в случае с отзывом разрешений. Решение этой проблемы - отдельная тема.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы