Как я могу делегировать проверки авторизации JAAS компании Shiro?

Я разрабатываю серверное приложение, которое требует аутентификации и авторизации на основе объектов. Мне нравится простота Shiro, но для совместимости с JAAS я написал LoginModule, который использует Apache Shiro в качестве базового механизма.

Но моя проблема в том, что я не смог найти способ делегировать проверки авторизации JAAS Широ. Как я могу этого добиться?


person Deniz Acay    schedule 20.04.2011    source источник
comment
Дениз, ты нашел способ использовать Широ с JAAS? Если нет, то какой подход вы выбрали? Спасибо, Кевин   -  person Kevin Welker    schedule 16.08.2011
comment
Моей главной заботой было использование Shiro для защиты JMX, которая использует JAAS в качестве основного метода защиты. Я решил эту проблему, внедрив JMXAuthenticator, который создает изменяемый субъект JAAS в текущем контексте управления доступом и сохраняет субъект Shiro в наборе личных учетных данных субъекта JAAS. Позже я реализовал LoginModule, который фактически был оболочкой интерфейса Shiro Authenticator (расширенного SecurityManagers).   -  person Deniz Acay    schedule 17.08.2011
comment
Возможно, вы могли бы предоставить больше информации о том, в чем именно проблема, включая код вашего LoginModule, какую ошибку вы получаете и конфигурацию времени выполнения.   -  person Martín Straus    schedule 03.10.2017


Ответы (1)


Примечание. Ответ касается общего случая, когда внешняя система авторизации должна быть интегрирована с JVM с помощью стандартной структуры безопасности. Это не специфично для Shiro или JMX, поскольку я не знаком ни с одним из них.


Концептуально кажется, что вы находитесь после точки принятия решения о политике (PDP) — средства, где оцениваются запросы авторизации (разрешено ли объекту X делать Y?), то есть. JDK предлагает несколько из них:

  1. Действующий SecurityManager, а именно его группа checkXXX методов.
  2. Класс ProtectionDomain, особенно его метод implies(Permission) .
  3. Ключевой implies(ProtectionDomain, Permission) метод эффективного Policy .
  4. Во-вторых, implies методы CodeSource, PermissionCollection, Permission и Principal.

Любой из вышеупомянутых методов можно переопределить, чтобы настроить с возрастающей степенью детализации функциональные возможности концептуального PDP. Следует отметить, что JAAS (вопреки тому, что следует из названия) на самом деле не привнесла с собой собственный PDP; скорее, он предоставил средства для домена и политики для поддержки запросов на основе принципала в дополнение к исходному фактору доверия происхождения кода. Следовательно, на мой взгляд, ваше требование оставаться совместимым с JAAS в основном означает желание использовать (исходную плюс JAAS) модель авторизации Java SE, также известную как песочница, в которой я сомневаюсь, что вы желание. Фреймворки, такие как Shiro, как правило, используются, когда стандартная модель считается слишком низкоуровневой и/или требовательной к производительности; другими словами, когда логика авторизации не обязана оценивать каждый кадр стека для заданного набора факторов доверия, поскольку эти факторы чаще не зависят от контекста, чем нет. В зависимости от справедливости моего предположения для рассмотрения возникают три основных случая:

  1. Авторизация является AccessControlContext-независимой. Собственные атрибуты авторизации Shiro (SNAA), какими бы они ни были, применяются ко всему потоку. Происхождение кода значения не имеет.
  2. Имеет значение происхождение кода, требующее использования песочницы. SNAA по-прежнему AccessControlContext-независимы.
  3. Происхождение кода и SNAA важны и AccessControlContext-зависимы.

1. Авторизация, основанная исключительно на SNAA

  1. Управляйте аутентификацией, как считаете нужным. Если вы хотите продолжать использовать javax.security.auth SPI JAAS для аутентификации, забудьте об установлении стандартного Subject в качестве результата аутентификации, вместо этого напрямую привязав специфичный для Shiro SPI к локальному хранилищу потока. Таким образом, вы получаете более удобный доступ к SNAA и избегаете необходимости использовать AccessControlContext (и страдаете от потенциальных штраф за производительность), за их поиск.

  2. Подкласс SecurityManager, переопределяющий как минимум два метода checkPermission таким образом, чтобы они

    1. translate, if necessary, the Permission argument into something Shiro's PDP (SPDP) understands, prior to
    2. делегирование SPDP с локальными SNAA и разрешениями потока (и выдача SecurityException в случае отказа в доступе сигнала SPDP).

    Перегрузка, получающая контекст безопасности, может просто игнорировать соответствующий аргумент. Во время инициализации приложения создайте и установите (System::setSecurityManager) свою реализацию.


2. Гибридная авторизация, сочетающая происхождение кода с контекстно-независимыми SNAA.

  1. Управляйте аутентификацией, как считаете нужным; еще раз свяжите специфичный для Широ Subject с самим потоком.
  2. Подкласс SecurityManager, переопределяющий как минимум два метода checkPermission, на этот раз таким образом, что они делегируют как SPDP, так и/или переопределенной реализации (которая, в свою очередь, вызывает checkPermission, соответственно, в текущем или предоставленном контексте управления доступом). К каким из них и в каком порядке следует обращаться для любого данного разрешения, конечно, зависит от реализации. Когда должны быть вызваны оба, SPDP следует запрашивать первым, так как он, вероятно, ответит быстрее, чем контекст управления доступом.
  3. Если SPDP должен дополнительно обрабатывать оценку разрешений, предоставленных коду, происходящему из определенного места и/или набора лиц, подписывающих код, вам также придется создать подкласс Policy, реализовав implies(ProtectionDomain, Permission) таким образом, чтобы, как и SecurityManager::checkPermission выше, он передал некоторое понятное представление домен (обычно только его CodeSource) и аргументы разрешения — но логически не SNAA — в SPDP. Реализация должна быть максимально эффективной, поскольку она будет вызываться один раз для каждого домена в каждом контексте управления доступом в checkPermission времени. Создайте и установите (Policy::setPolicy) вашу реализацию.

3. Гибридная авторизация, сочетающая происхождение кода с SNAA, оба контекстно-зависимые.

  1. Управляйте аутентификацией, как считаете нужным. К сожалению, в данном случае часть обработки темы не так тривиальна, как создание ThreadLocal.

  2. Создайте подкласс, создайте экземпляр и установите Policy, который выполняет объединенные функции SecurityManager::checkPermission и Policy::implies, как описано по отдельности во втором случае.

  3. Создайте и установите стандартный файл SecurityManager.

  4. Создайте подкласс ProtectionDomain, способный хранить и отображать SNAA.

  5. Создайте1 DomainCombiner< / а> что

    1. построен с использованием SNAA;

    2. реализует combine(ProtectionDomain[], ProtectionDomain[]) так, что

      1. it replaces the first (the "current" context) array argument's domains with equivalent instances of the custom implementation;
      2. затем добавляет единицы второго (назначенного или унаследованного контекста) аргумента, если таковые имеются, к первому как есть; И наконец
      3. возвращает конкатенацию.

    Подобно Policy::implies, реализация должна быть эффективной (например, за счет устранения дубликатов), поскольку она будет вызываться каждый раз, когда будут вызываться методы getContext и checkPermission AccessController.

  6. После успешной аутентификации создайте новый AccessControlContext, который является оберткой для текущего, вместе с экземпляром пользовательского DomainCombiner, в свою очередь, обернув SNAA. Оберните код, который будет выполняться после этой точки, внутри вызова AccessController::doPrivilegedWithCombiner, также передав контекст управления доступом замены.


1    Вместо использования настраиваемых доменов и собственной реализации комбайнера существует также, казалось бы, более простая альтернатива преобразования SNAA в Principal и, используя стандартные SubjectDomainCombiner, привязки их к текущим доменам AccessControlContext (как указано выше, или просто через Subject::doAs ). Снижает ли этот подход эффективность политики, зависит в первую очередь от глубины стека вызовов (сколько отдельных доменов содержит контекст управления доступом). В конце концов оптимизации кэширования, которые, как вы думали, можно было бы избежать в составе объединителя доменов, нанесут вам ответный удар при разработке политики, так что это, по сути, дизайнерское решение, которое вам придется принять на этом этапе.

person Uux    schedule 10.01.2018
comment
Хотя я нашел решение и ответил на свой вопрос 6 лет назад, полезный объем информации, которую вы предоставили здесь для всех, кто наткнется на этот вопрос, определенно заслуживает того, чтобы быть принятым ответом. - person Deniz Acay; 13.01.2018