Как стать автором
Обновить

Комментарии 11

Мы тоже пытались реализовать авторизацию (не путать с аутентификацией - с ней всё норм) через Keycloak, но не взлетело. Например, как банально получить перечень записей, но отфильтровать те, к которым у пользователя нет доступа? Запрашивать все записи и потом по каждой отправлять запрос в Keycloak? Как это всё будет стыковаться с пагинацией? Допустим на странице должно быть 10 записей, из них доступ есть только к 7. Нужно дозапросить ещё 3 записи?..

Я просто не понимаю как это может работать хоть для сколько-нибудь сложного приложения. Хотя сам Keycloak клёвый. У нас приложение вместе с Keycloak, ApacheDS (для тестовых пользователей) и т.д. завернуто в Docker Compose. При запуске Keycloak автоматически импортируется json-конфиг с настройками realm, интеграцией с ApacheDS. Всё это легко разворачивается на стенде, на машинах разработчиков, в тестовом окружении.

Как вариант можно написать свой плагин, который будет имплементировать нужный Вам АПИ ендпоинт.

Всё равно останется проблема, что записи в одном сервисе (само приложение), а разрешения для них - в другом (Keycloak). И нужно получать данные из двух источников, как-то мержить их. Здесь в принципе не сделать простую и быструю реализацию. Гораздо проще хранить и записи, и разрешения в одной базе и получать всё одним SQL-запросом.

Например, как банально получить перечень записей, но отфильтровать те, к которым у пользователя нет доступа? Запрашивать все записи и потом по каждой отправлять запрос в Keycloak? Как это всё будет стыковаться с пагинацией? Допустим на странице должно быть 10 записей, из них доступ есть только к 7. Нужно дозапросить ещё 3 записи?..

Мы у себя запрашиваем доступные scope для нужного нам ресурса и дальше уже подставляем нужные фильтры в сам запрос.

Не очень понимаю... Если нужно ограничить доступ по типам ресурсов, то можно использовать роли из Keycloak. Например, одна роль позволяет просматривать новости, другая - статьи.

Немного более сложный вариант. Допустим статьи могут быть двух типов: обычные для всех и премиальные для подписчиков. Это тоже можно решить через роли "обычный пользователь", "подписчик", "супер-подписчик" и т.д.

А если ещё более сложный вариант типа Google Документов? Пользователи могут создавать документы, выдавать к ним доступ другим пользователям. Причём, этих документов в системе миллионы. В Keycloak должна храниться информация о каждом таком документе? Затем в него отправляется запрос с id документа и id пользователя и Keycloak отвечает есть ли у пользователя доступ к этому документу?

Вы меня не поняли.

В Keycloak для авторизации есть две сущности:

  • Ресурсы.

  • Область действий.

Например есть у нас ресурс (resource): статьи.
И область действий (scope): читать и чтение за деньги. Которую назначаем для ресурса и привилегий.

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

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

Далее перед запросом списка статей из репозитория\БД, проверяю каждую область действий по отдельности:

  • Могу видеть все статьи? - Если да, то делаем запрос без фильтров и условий.

  • Могу видеть платные статьи? - Если нет, то ограничиваем тип статей.

  • Могу видеть бесплатные статьи? Если нет, то выдаю ошибку 403.

Моя реализация может быть не правильной.

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

Спасибо, теперь кажется понял. По сути resource и scope - это возможно чуть более правильный вариант по сравнению с ролями. Но пообъектную проверку доступа через него всё равно не сделать.

Или пообъектной проверки и нет в Keycloak вообще? Интересно что имеется в виду под ресурсом в документации на сервер авторизации. Это типы ресурсов, например, "обычная статья", "платная статья" и т.д.? Или речь о конкретных ресурсах: "статья с идентификатором 123 про Keycloak", "статья с ид 234 про OIDC" и т.д.? Или ресурсом может быть что угодно: и тип ресурсов, и конкретный ресурс?

То, что в Keycloak можно описать правила доступа к типам ресурсов это понятно. Либо через роли, либо через скоупы. Но если нужно разделение доступа на уровне отдельных объектов, то по-моему Keycloak уже не очень подходит.

Интересно что имеется в виду под ресурсом в документации на сервер авторизации. Это типы ресурсов, например, "обычная статья", "платная статья" и т.д.?

Статья - это и есть ресурс. Это может быть что-то абстрактное.
Например помимо статей, есть ещё новости. Можно разбить на меньшие понятия, например научные и развлекательные статьи.

"платный", можно выделить к scope (мы так у себя сделали назвав примерно как view_paid), но ни что не мешает сделать как resource.

Но если нужно разделение доступа на уровне отдельных объектов, то по-моему Keycloak уже не очень подходит.

Мы в будущем планируем писать свой велосипед, из-за того что есть кейсы, которые Keycloak не может разрешить. Будем конечно ещё копаться.

Видимо это меня и сбивает, потому что обычно под ресурсом подразумевается конкретный объект. Например, в REST это может быть ресурсами:

  • https://example.com/api/articles/1

  • https://example.com/api/articles/2

  • https://example.com/api/articles/3

  • ...

А статьи, новости и т.д. - это типы ресурсов, а не конкретные ресурсы. Или допустим в документации упоминается "fine-grained authorization", "fine-grained permissions" - у меня сразу возникают ассоциации с ограничением доступа на уровне отдельных объектов или даже отдельных атрибутов, с чем-нибудь типа Row-Level Security, но реально имеется в виду что-то более простое.

Ну либо я не совсем верно понял.

Вот гайд по которому мы реализовывали у себя пермиссии: https://www.keycloak.org/docs/latest/authorization_services/index.html#resource

Там они пишут что это может быть как в целом "банковский счёт", так и конкретный "банковский счёт Алисы".

Да, по ссылке написано:

Every resource has a unique identifier that can represent a single resource or a set of resources. For instance, you can manage a Banking Account Resource that represents and defines a set of authorization policies for all banking accounts. But you can also have a different resource named Alice’s Banking Account, which represents a single resource owned by a single customer, which can have its own set of authorization policies.

Т.е. под ресурсом они имеют в виду и коллекцию (тип) ресурсов, и конкретные ресурсы.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории