Масштабируемая аутентификация на основе ролей
В настоящее время я разрабатываю систему аутентификации на основе ролей для ресурсов, у которых многие пользователи имеют разные права доступа к ней.
Роль может быть отдельным пользователем или группой ролей (таким образом, роль - это дерево ролей). (см. рисунок ниже)
Ресурс может иметь несколько свойств аутентификации (например, чтение, запись, удаление), где каждая из них представляет собой список ролей, которым разрешено выполнять доступ к операции. (см. рисунок ниже)
Проблема в том, что если я хочу проверить, имеет ли пользователь право на доступ к свойству, я должен пройти через n деревьев в худшем случае (где n - количество ролей, назначенных для свойства).
Так, например, чтобы проверить, может ли "Макс" прочитать свойство, мне может понадобиться проверить деревья "Маркетинг", "Управление" и "Администрирование", если они содержат "Макс".
Знаете ли вы какой-либо алгоритм или альтернативный подход, который удаляет довольно дорогой поиск по дереву при сохранении системы ролей или чего-то такого же мощного.
Идеальный случай - это поиск типа O(log(n)) для n ролей.
Спасибо, Фионн
3 ответа
Вы измерили это и определили, что этот обход является узким местом производительности?
Я никогда не видел систему с таким количеством ролей / уровней, что стоимость обхода такой структуры стала бы проблемой. И если дерево действительно такое большое, я бы больше беспокоился о том, что администраторам будет трудно понять, кто уполномочен делать что.
Что касается масштабируемости, я бы обычно использовал кеш ASP.NET для кеширования полного дерева, которое отображается между ресурсами и ролями, с подходящим временем ожидания кеша. И отдельно кэшируйте сопоставление от пользователей к ролям (например, в сеансе или с помощью пользовательского ключа в кэше ASP.NET).
Доступ к информации из кэша, как правило, будет ослепительно быстрым по сравнению с каждым обращением к базе данных.
Если вы поместите свои роли в базу данных SQL, поиск будет работать в основном так, как вы описали. Я могу помочь вам со структурой базы данных, если вам интересно.
Вы должны поменять свои указатели.
"Гарри" является членом "Администраторов сайта 2", у которых есть "администраторы" доступа к "сайту 2", поэтому он может "удалять", "писать" и "читать этот контент".
Почему "Администрация" должна быть общей вещью между "Гарри" и "Джо", мне не ясно. Гарри - администратор на одном сайте, а просто пользователь на другом, а Джо - наоборот.