Как я могу делегировать проверки авторизации JAAS Широ? - PullRequest
63 голосов
/ 21 апреля 2011

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

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

1 Ответ

3 голосов
/ 10 января 2018

Примечание. Ответ касается общего случая, когда внешняя система авторизации должна быть интегрирована с 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 не зависит.Широкие атрибуты авторизации (SNAA), какими бы они ни были, применяются ко всему потоку.Происхождение кода не имеет значения.
  2. Происхождение кода имеет значение, обязательное использование песочницы.SNAA по-прежнему AccessControlContext -независимы.
  3. Происхождение кода и SNAA являются релевантными и AccessControlContext - зависимыми .

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

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

    1. преобразуют, если необходимо, аргумент Permission в нечто, понятное для PDP (SPDP) Широ, до
    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) и аргументы разрешения- но логически не СНС - в СПДП.Реализация должна быть максимально возможной, так как она будет вызываться один раз для каждого домена в контексте управления доступом в checkPermission раз.Создайте и установите (Policy::setPolicy) свою реализацию.

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

  1. Управляйте аутентификацией, как считаете нужным.К сожалению, часть обработки субъекта не так тривиальна, как создание ThreadLocal в этом случае.
  2. Подкласс, создание экземпляра и установка Policy, который выполняет объединенные обязанности SecurityManager::checkPermission и Policy::implies, так какиндивидуально описано во втором случае.
  3. Создание и установка стандартного SecurityManager.
  4. Создание подкласса ProtectionDomain, способного хранить и отображать SNAA.
  5. Автор 1 a DomainCombiner, который

    1. построен с использованием SNAA;
    2. реализует combine(ProtectionDomain[], ProtectionDomain[]) такихчто

      1. заменяет домены аргумента первого («текущего» контекста) массива эквивалентными экземплярами пользовательской реализации;
      2. затем добавляет второй («назначенный» или «унаследованный»).«контекстные» аргументы, если таковые имеются, к прежнему как есть;и, наконец,
      3. возвращает конкатенацию.

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

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

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

...