Как я могу делегировать проверки авторизации JAAS Сиро?
Я разрабатываю серверное приложение, которое требует аутентификации и авторизации на основе объектов. Мне нравится простота Сиро, но для совместимости с JAAS я написал LoginModule, который использует Apache Shiro в качестве базового механизма.
но моя проблема в том, что я не мог найти способ делегировать проверки авторизации JAAS Сиро. Как я могу достичь этого?
1 ответов
Примечание: ответ касается общего случая, когда внешняя система авторизации должна быть интегрирована с JVM, с помощью стандартной системы безопасности. Это не Широ - или с JMX-конкретные, как я знакома с ни.
концептуально, кажется, что вы находитесь после точки принятия решения политики ( PDP) -- средство, где запросы авторизации ( " разрешено ли сущности X делать Y?") оцениваются, то есть. JDK предлагает несколько эти:
- эффективное
SecurityManager
, в частностиcheckXXX
группа методов. - на
ProtectionDomain
класс, особенно егоimplies(Permission)
метод. - ключ
implies(ProtectionDomain, Permission)
метод эффективногоPolicy
. - кроме того,
implies
способыCodeSource
,PermissionCollection
,Permission
, иPrincipal
.
любой из вышеупомянутых методов может быть переопределен для настройки, при возрастающей детализации, функциональности концептуального PDP. Следует отметить, что JAAS (вопреки тому, что предполагает его название) на самом деле не принес свой собственный PDP; скорее, он предоставил означает для домена и политики для поддержки запросов на основе принципала в дополнение к исходному коэффициенту доверия источника кода. Поэтому, на мой взгляд, ваш требование оставаться "совместимым с JAAS" в основном переводится на желание использовать (original-plus-JAAS) модель авторизации Java SE, a.к. a. the песочница, в которой я сомневаюсь, что вы хотите. Такие структуры, как Shiro, как правило, используются, когда стандартная модель считается либо слишком низкоуровневой и/или трудоемкой; другими словами, когда логика авторизации не нужно оцените каждый кадр стека для заданного набора факторов доверия из-за этих факторов быть чаще контекстно-нечувствительным, чем нет. В зависимости от обоснованности моего предположения, для рассмотрения возникают три основных случая:
- авторизация
AccessControlContext
-независимые. Атрибуты авторизации Shiro-native (SNAAs), каковы бы они ни были, применяются ко всему потоку. Происхождение кода не имеет значения. - происхождение кода имеет значение, требуя использования песочницы. SNAAs еще
AccessControlContext
-независимые. - код origin и SNAAs являются релевантными и
AccessControlContext
-зависимая.
1. Авторизация, основанная исключительно на SNAAs
- управление аутентификацией, как вы считаете нужным. Если вы хотите продолжить использовать JAAS'
javax.security.auth
SPI для аутентификации, забудьте об установлении стандартаSubject
в качестве результата проверки подлинности, вместо этого напрямую связывая специфичный для Shiro с локальным хранилищем потоков. Таким образом, вы получаете более удобный доступ к SNAAs и избегаете использованияAccessControlContext
(и страдать от потенциала производительность), для их извлечения. -
подкласс
SecurityManager
, переопределяя по крайней мере дваcheckPermission
методы такие, что они- перевести, если необходимо,
Permission
аргумент в то, что PDP Широ (SPDP) понимает, до - делегирование SPDP с потоком-локальными SNAAs и разрешением (и бросание
SecurityException
если доступ к сигналу SPDP отрицание.)
перегрузка приема контекста безопасности может просто игнорировать соответствующий аргумент. Во время инициализации приложения создайте экземпляр и установите (
System::setSecurityManager
) своего осуществления. - перевести, если необходимо,
2. Гибридная авторизация, сочетающая происхождение кода с контекстно-нечувствительными SNAAs
- управление аутентификацией, как вы считаете нужным; еще раз свяжите Shiro-specific
Subject
с ниткой себя. - подкласс
SecurityManager
, переопределяя по крайней мере дваcheckPermission
методы, на этот раз такие, что они делегируют как SPDP, так и/или переопределенную реализацию (которая, в свою очередь, вызываетcheckPermission
on, соответственно, текущий или поставляемый контекст управления доступом). Какой из них (ов) и в каком порядке следует проконсультироваться для получения любого данного разрешения, конечно, зависит от реализации. Когда оба должны быть вызваны, сначала следует запросить SPDP, так как он, вероятно, ответит быстрее чем контекст управления доступом. - если SPDP должен дополнительно обрабатывать оценку разрешений, предоставленных коду, происходящему из определенного местоположения и / или набора подписчиков кода, вам также придется подкласс
Policy
, осуществляетimplies(ProtectionDomain, Permission)
такие, что какSecurityManager::checkPermission
выше, он передает некоторое понятное представление домена (обычно только егоCodeSource
) и аргументы разрешения - но логически не SNAAs -- к SPDP. Осуществление должно быть эффективен, насколько это возможно, поскольку он будет вызываться один раз на домен в контексте управления доступом по адресуcheckPermission
времени. Создать и установить (Policy::setPolicy
) своего осуществления.
3. Гибридная авторизация, сочетающая происхождение кода с SNAAs, оба контекстно-зависимые
- управление аутентификацией, как вы считаете нужным. К сожалению, часть обработки темы не так тривиальна, как создание
ThreadLocal
в этом случае. - подкласс, создать и установить
Policy
который выполняет объединенные обязанностиSecurityManager::checkPermission
иPolicy::implies
, как индивидуально описано во втором случае. - создать экземпляр и установить стандартный
SecurityManager
. - создать
ProtectionDomain
подкласс, способный хранить и подвергать действию SNAAs. -
автор1 a
DomainCombiner
это- построено с SNAAs;
-
осуществляет
combine(ProtectionDomain[], ProtectionDomain[])
такой, что- он заменяет домены первого ("текущего" контекста) аргумента массива эквивалентными экземплярами пользовательской реализации;
- затем добавляет второй ("назначенный "или" унаследованный " контекст) аргумент, если таковой имеется, к первому как есть; и, наконец,
- возвращает конкатенацию.
как
Policy::implies
реализация должна быть эффективной (например, путем устранения повторений), так как он будет вызывается каждый раз, когдаgetContext
иcheckPermission
AccessController
методы. - после успешной аутентификации создайте новый
AccessControlContext
это обертывает текущий, вместе с экземпляром пользовательскогоDomainCombiner
в свою очередь оборачивать SNAAs. Код обруча должен быть выполнен за ссылки "в" вAccessController::doPrivilegedWithCombiner
invocation, также передавая вдоль контекста управления доступом замены.
1 вместо использования пользовательских доменов и собственных реализация объединителя, есть также, казалось бы, более простая альтернатива перевода SNAAs в Principal
s и, используя стандарт SubjectDomainCombiner
, привязывая их к текущему AccessControlContext
домены (как указано выше, или просто через Subject::doAs
). Снижает ли этот подход эффективность политики, зависит в первую очередь от глубины стека вызовов (сколько различных доменов содержит контекст управления доступом). В конечном итоге оптимизации кэширования вы думали, что можете избежать реализации как часть домена combiner поразит вас при разработке политики, поэтому это, по сути, дизайнерское решение, которое вам придется принять в этот момент.