Как я могу делегировать проверки авторизации 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.authSPI для аутентификации, забудьте об установлении стандартаSubjectв качестве результата проверки подлинности, вместо этого напрямую связывая специфичный для Shiro с локальным хранилищем потоков. Таким образом, вы получаете более удобный доступ к SNAAs и избегаете использованияAccessControlContext(и страдать от потенциала производительность), для их извлечения. -
подкласс
SecurityManager, переопределяя по крайней мере дваcheckPermissionметоды такие, что они- перевести, если необходимо,
Permissionаргумент в то, что PDP Широ (SPDP) понимает, до - делегирование SPDP с потоком-локальными SNAAs и разрешением (и бросание
SecurityExceptionесли доступ к сигналу SPDP отрицание.)
перегрузка приема контекста безопасности может просто игнорировать соответствующий аргумент. Во время инициализации приложения создайте экземпляр и установите (
System::setSecurityManager) своего осуществления. - перевести, если необходимо,
2. Гибридная авторизация, сочетающая происхождение кода с контекстно-нечувствительными SNAAs
- управление аутентификацией, как вы считаете нужным; еще раз свяжите Shiro-specific
Subjectс ниткой себя. - подкласс
SecurityManager, переопределяя по крайней мере дваcheckPermissionметоды, на этот раз такие, что они делегируют как SPDP, так и/или переопределенную реализацию (которая, в свою очередь, вызываетcheckPermissionon, соответственно, текущий или поставляемый контекст управления доступом). Какой из них (ов) и в каком порядке следует проконсультироваться для получения любого данного разрешения, конечно, зависит от реализации. Когда оба должны быть вызваны, сначала следует запросить 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иcheckPermissionAccessControllerметоды. - после успешной аутентификации создайте новый
AccessControlContextэто обертывает текущий, вместе с экземпляром пользовательскогоDomainCombinerв свою очередь оборачивать SNAAs. Код обруча должен быть выполнен за ссылки "в" вAccessController::doPrivilegedWithCombinerinvocation, также передавая вдоль контекста управления доступом замены.
1 вместо использования пользовательских доменов и собственных реализация объединителя, есть также, казалось бы, более простая альтернатива перевода SNAAs в Principals и, используя стандарт SubjectDomainCombiner, привязывая их к текущему AccessControlContextдомены (как указано выше, или просто через Subject::doAs). Снижает ли этот подход эффективность политики, зависит в первую очередь от глубины стека вызовов (сколько различных доменов содержит контекст управления доступом). В конечном итоге оптимизации кэширования вы думали, что можете избежать реализации как часть домена combiner поразит вас при разработке политики, поэтому это, по сути, дизайнерское решение, которое вам придется принять в этот момент.