Мы пытаемся определить лучший способ авторизации пользователей в микросервисной архитектуре, в то же время гарантируя, что у микросервисов ограниченные разрешения. Наша архитектура использует центральную службу авторизации для обработки выдачи токенов JWT.
У нас есть следующие требования:
Пользователи должны быть ограничены для выполнения определенных ролей. например, пользователь должен иметь возможность только создавать / изменять / читать контент, которым он владеет.
Микросервисы должны быть ограничены только теми разрешениями, которые им требуются. например, микросервису, которому нужно только читать данные из другой службы, должно быть явно запрещено записывать данные в эту службу.
В качестве примера, предположим, у нас есть система, где пользователи могут загружать изображения в сервис хранилища изображений. У нас есть служба тегов, которая автоматически помечает фотографии с указанием местоположения. Пользователи могут только CRUD свои собственные фотографии. Служба тегов может считывать любое изображение из службы хранилища изображений, однако не может изменять / удалять.
Что является хорошим способом для достижения вышеизложенного с использованием токенов JWT? Некоторые решения, которые мы обсудили:
Служба хранилища изображений предоставляет 2 API-интерфейса: один, доступный извне (предоставляющий пользователю доступ к CRUD), и другой, доступный внутри (предоставляющий доступ только для чтения). Кажется негибким - что если другой внутренней службе требуется доступ на чтение / запись ко всем изображениям (например, к той, которая автоматически удаляет явные изображения)?
Мы установили два разрешения в JWT пользователя, одно из которых CRUD_OwnImages, а другое READ_ForAnalysis. Служба тегов может видеть, есть ли у пользователя разрешения READ_ForAnalysis, и, если да, сделать соответствующий запрос. У нас есть другой микросервис, который проверяет, есть ли у пользователя CRUD_OwnImages для операций CRUD над его изображениями. Это накладывает ответственность на каждую микросервисную службу на то, чтобы гарантировать, что пользователь ограничен действиями, которые он требует. При таком подходе хранилище изображений не может ограничить каждую микросервисную службу, поэтому оно потенциально ненадежно и подвержено ошибкам.
Мы даем микросервису тегов свой собственный пользователь с разрешением READ_ForAnalysis. Затем, когда служба тегирования запрашивает изображения из хранилища изображений, им предоставляется доступ к ним, но запрещено изменять их. Пользователь пользователя имеет только разрешение CRUD_OwnImages, поэтому он может получать и получать доступ только к своим изображениям из внешнего интерфейса. Если другой сервис нуждается в CRUD для всех данных, мы можем предоставить ему CRUD_AllData или аналогичный. Нам нравится этот подход, поскольку теперь каждая служба отвечает за свои собственные данные (а не за дублирование логики между несколькими службами), но что, если службе требуются как разрешения пользователя, так и разрешения микросервиса? Можем ли мы безопасно отправить два токена JWT (и пользователя, и микросервиса)? Есть ли способ надежно объединить разрешения и отправить их через? например
Проблема усугубляется, если пользовательская информация необходима дальше вниз по течению (на расстоянии 2 или 3 микросервисов). Неужели мы просто предполагаем, что сами микросервисы должны ограничиваться действиями, которые им нужны, а не делать это явно?
Ответы:
В общем, как можно больше операций должно быть привязано к реальному человеку. Это заставляет людей проходить аутентификацию должным образом, оно требует единой согласованной стратегии авторизации и является важной частью обеспечения целостного контрольного журнала.
И вообще, у вас есть три вида сценариев с микросервисами:
1. Пользователь заходит, загружает фотографию, и она должна быть помечена. Отлично. Фотосервис может просто передавать JWT в службу тегов (или наоборот, в зависимости от направления вашей зависимости), и если у пользователя нет прав на выполнение подоперации, вы предпринимаете соответствующее действие (возможно, загрузите фотографию без тега , может вернуть ошибку, может что-то еще).
2. Пользователь заходит, загружает фотографию, и она должна быть помечена ... но не сейчас. Здорово. Вы обрабатываете фотографию сейчас как обычно. Позже, когда происходит тегирование (обработка событий / сообщений, обработка команд в стиле CQRS, некоторая периодическая обработка заданий и т. Д.), Служба тегов будет выдавать себя за пользователя (скорее всего, с помощью общего секретного ключа для запроса пользовательского JWT от auth), а затем выполнит подоперация от имени исходного запросчика (со всеми их разрешениями и ограничениями). Этот метод имеет обычную проблему с асинхронными операциями, когда трудно возвращать ошибки пользователю, если что-то идет не так, но если вы используете этот шаблон для кросс-сервисных операций, вы уже решили это.
3. Некоторые подсистемы должны делать вещи вне контекста пользователя. Может быть, у тебя есть ночная работа по архивированию старых изображений. Возможно, ваши теги должны быть консолидированы ... В этом случае вы, вероятно, захотите, чтобы у каждого из этих участников был свой псевдопользователь с ограниченными разрешениями и уникальный идентификатор для контрольного журнала.
Какой из них использовать, зависит от вашего сценария, ваших потребностей и допустимого риска. И, конечно же, это всего лишь неполный набор обобщений с широкими штрихами.
Но в целом сами микросервисы не должны быть пользователями, если это возможно.
источник