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

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

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

1 ответов


Примечание: ответ касается общего случая, когда внешняя система авторизации должна быть интегрирована с JVM, с помощью стандартной системы безопасности. Это не Широ - или с 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" в основном переводится на желание использовать (original-plus-JAAS) модель авторизации Java SE, a.к. a. the песочница, в которой я сомневаюсь, что вы хотите. Такие структуры, как Shiro, как правило, используются, когда стандартная модель считается либо слишком низкоуровневой и/или трудоемкой; другими словами, когда логика авторизации не нужно оцените каждый кадр стека для заданного набора факторов доверия из-за этих факторов быть чаще контекстно-нечувствительным, чем нет. В зависимости от обоснованности моего предположения, для рассмотрения возникают три основных случая:

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

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

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

    1. перевести, если необходимо,Permission аргумент в то, что PDP Широ (SPDP) понимает, до
    2. делегирование SPDP с потоком-локальными SNAAs и разрешением (и бросание SecurityException если доступ к сигналу SPDP отрицание.)

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


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

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

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

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

    1. построено с SNAAs;
    2. осуществляет combine(ProtectionDomain[], ProtectionDomain[]) такой, что

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

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

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

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