java - ¿Cómo puedo delegar las verificaciones de autorización de JAAS en Shiro?
authorization authentication (1)
Nota: La respuesta se dirige al caso general en el que un sistema de autorización externo debe integrarse con la JVM, por medio del marco de seguridad estándar. No es específico de Shiro o JMX, ya que no estoy familiarizado con ninguno de los dos.
Conceptualmente, parece que está después del punto de decisión de política (PDP): el recurso donde se evalúan las consultas de autorización ( "¿la entidad X puede hacer Y?" ), Es decir. El JDK ofrece varios de estos:
- El
SecurityManager
efectivo, específicamente su grupo de métodoscheckXXX
. - La clase
ProtectionDomain
, particularmente su métodoimplies(Permission)
. - La clave
implies(ProtectionDomain, Permission)
métodoimplies(ProtectionDomain, Permission)
de laPolicy
efectiva. - En
CodeSource
, los métodosCodeSource
deCodeSource
,PermissionCollection
,Permission
yPrincipal
.
Cualquiera de los métodos mencionados anteriormente puede anularse para personalizar, en granularidad ascendente, la funcionalidad del PDP conceptual. Debe notarse que JAAS (en contra de lo que su nombre sugiere) realmente no trajo su propio PDP; más bien, proporcionó los means para que el dominio y la política admitan consultas basadas en el principal, además del factor de confianza original del origen del código. Por lo tanto, a mi juicio, su requisito de permanecer "compatible con JAAS" se traduce básicamente en querer usar el modelo de autorización Java SE (original-más-JAAS), también conocido como sandbox, que dudo que sea lo que usted desea. Los marcos tales como Shiro tienden a ser empleados cuando el modelo estándar se considera de muy bajo nivel y / o de alto rendimiento; en otras palabras, cuando la lógica de autorización no necesita evaluar cada marco de pila individual para un conjunto dado de factores de confianza, debido a que esos factores son más insensibles al contexto que no. Dependiendo de la validez de mi suposición, se presentan tres casos principales para el examen:
- La autorización es
AccessControlContext
-independent. Los atributos de autorización shiro-nativos (SNAA), sean los que sean, se aplican a todo el hilo. El origen del código es irrelevante. - Código de origen importa, el uso obligatorio de la caja de arena. Los SNAA siguen siendo
AccessControlContext
-independent. - El origen del código y las SNAA son relevantes y
AccessControlContext
- dependent .
1. Autorización basada únicamente en SNAAs
- Administre la autenticación como mejor le parezca. Si desea continuar utilizando JAA ''
javax.security.auth
SPI para la autenticación, olvídese de establecer unSubject
estándar como el resultado de autenticación, en lugar de vincular directamente el específico de Shiro al almacenamiento local de subprocesos. De esta forma, obtiene un acceso más conveniente a las SNAA, y evita tener que usarAccessControlContext
(y sufrir la posible penalización del rendimiento ), para su recuperación. Subclass
SecurityManager
, anulando al menos los dos métodoscheckPermission
tales que- traduzca, si es necesario, el argumento de
Permission
a algo que el PDP de Shiro (SPDP) comprenda, antes de - delegando al SPDP con el SNAA local de hilos y el permiso (y lanzando una
SecurityException
caso de que el acceso a la señal SPDP sea denegado).
La sobrecarga de recepción de contexto de seguridad simplemente puede ignorar el argumento correspondiente. En el momento de la inicialización de la aplicación,
System::setSecurityManager
instancia e instale (System::setSecurityManager
) su implementación.- traduzca, si es necesario, el argumento de
2. Autorización híbrida, que combina origen de código con SNAAs insensibles al contexto
- Administre la autenticación como mejor le parezca; una vez más asocie el
Subject
específico de Shiro con el hilo en sí. - Subclase
SecurityManager
, anulando al menos los dos métodoscheckPermission
, esta vez para que deleguen tanto en el SPDP como en la implementación anulada (que a su vez llama acheckPermission
, en consecuencia, el contexto de control de acceso actual o suministrado). Cuál (es) cual (es) y en qué orden se debe consultar para cualquier permiso dado, por supuesto, depende de la implementación. Cuando se deben invocar ambos, se debe consultar primero el SPDP, ya que probablemente responderá más rápido que el contexto de control de acceso. - Si el SPDP debe manejar adicionalmente la evaluación de los permisos otorgados al código que se origina en una determinada ubicación y / o conjunto de firmantes de código, también deberá subclasificar la
Policy
, la implementaciónimplies(ProtectionDomain, Permission)
tal que, comoSecurityManager::checkPermission
anterior , pasa una representación inteligible del dominio (normalmente solo suCodeSource
) y argumentos de permiso, pero lógicamente no los SNAA, al SPDP. La implementación debería ser eficiente en la medida de lo posible, ya que se invocará una vez por dominio por contexto de control de acceso en la hora decheckPermission
. Cree una instancia e instale (Policy::setPolicy
) su implementación.
3. Autorización híbrida, que combina origen de código con SNAA, ambos sensibles al contexto
- Administre la autenticación como mejor le parezca. Lamentablemente, la parte de manejo de temas no es tan trivial como la creación de
ThreadLocal
en este caso. - Subclase, creación de instancias e instalación de una
Policy
que realice las tareas combinadas deSecurityManager::checkPermission
yPolicy::implies
SecurityManager::checkPermission
, como se describe individualmente en el segundo caso. - Crea una instancia e instala un
SecurityManager
estándar. - Cree una subclase
ProtectionDomain
, capaz de almacenar y exponer los SNAA. Autor 1 un
DomainCombiner
que- está construido con los SNAA;
implements
combine(ProtectionDomain[], ProtectionDomain[])
tal que- reemplaza los dominios del argumento de la matriz (el contexto "actual") con instancias equivalentes de la implementación personalizada;
- luego agrega los argumentos del segundo (el contexto "asignado" o "heredado"), si corresponde, al primero tal como está; y por último
- devuelve la concatenación.
Al igual que
Policy::implies
, la implementación debe ser eficiente (por ejemplo, eliminando duplicados), ya que se invocará cada vez que se encuentren losgetContext
ycheckPermission
AccessController
.- Tras la autenticación exitosa, cree un nuevo
AccessControlContext
que envuelva el actual, junto con una instancia delDomainCombiner
personalizado, a su vez envolviendo los SNAA. Ajustar el código para que se ejecute más allá de ese punto "dentro" de una invocación deAccessController::doPrivilegedWithCombiner
, que también pasa a lo largo del contexto de control de acceso de reemplazo.
1 En lugar de utilizar dominios personalizados y su propia implementación de combinador, también existe la alternativa aparentemente más simple de traducir los SNAA en Principal
sy, utilizando el SubjectDomainCombiner
estándar, vincularlos a los dominios actuales de AccessControlContext
(como se SubjectDomainCombiner
anteriormente, o simplemente a través del Subject::doAs
). Si este enfoque reduce la eficiencia de la política depende principalmente de la profundidad de la pila de llamadas (cuántos dominios distintos comprende el contexto de control de acceso). Finalmente, las optimizaciones del almacenamiento en caché que creía que podría evitar implementar como parte del combinador de dominios le devolverán el impacto al crear la política, por lo que esto es esencialmente una decisión de diseño que tendrá que tomar en ese momento.
Estoy desarrollando una aplicación del lado del servidor que necesita autenticación y autorización en función de los objetos. Me gusta la simplicidad de Shiro, pero para ser compatible con JAAS, escribí un LoginModule que usa Apache Shiro como el mecanismo subyacente.
Pero mi problema es que no pude encontrar una forma de delegar las verificaciones de autorización de JAAS a Shiro. ¿Cómo puedo conseguir esto?