java authorization authentication jaas shiro

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:

  1. El SecurityManager efectivo, específicamente su grupo de métodos checkXXX .
  2. La clase ProtectionDomain , particularmente su método implies(Permission) .
  3. La clave implies(ProtectionDomain, Permission) método implies(ProtectionDomain, Permission) de la Policy efectiva.
  4. En CodeSource , los métodos CodeSource de CodeSource , PermissionCollection , Permission y Principal .

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:

  1. 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.
  2. Código de origen importa, el uso obligatorio de la caja de arena. Los SNAA siguen siendo AccessControlContext -independent.
  3. El origen del código y las SNAA son relevantes y AccessControlContext - dependent .

1. Autorización basada únicamente en SNAAs

  1. 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 un Subject 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 usar AccessControlContext (y sufrir la posible penalización del rendimiento ), para su recuperación.
  2. Subclass SecurityManager , anulando al menos los dos métodos checkPermission tales que

    1. traduzca, si es necesario, el argumento de Permission a algo que el PDP de Shiro (SPDP) comprenda, antes de
    2. 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.

2. Autorización híbrida, que combina origen de código con SNAAs insensibles al contexto

  1. Administre la autenticación como mejor le parezca; una vez más asocie el Subject específico de Shiro con el hilo en sí.
  2. Subclase SecurityManager , anulando al menos los dos métodos checkPermission , esta vez para que deleguen tanto en el SPDP como en la implementación anulada (que a su vez llama a checkPermission , 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.
  3. 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ón implies(ProtectionDomain, Permission) tal que, como SecurityManager::checkPermission anterior , pasa una representación inteligible del dominio (normalmente solo su CodeSource ) 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 de checkPermission . 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

  1. 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.
  2. Subclase, creación de instancias e instalación de una Policy que realice las tareas combinadas de SecurityManager::checkPermission y Policy::implies SecurityManager::checkPermission , como se describe individualmente en el segundo caso.
  3. Crea una instancia e instala un SecurityManager estándar.
  4. Cree una subclase ProtectionDomain , capaz de almacenar y exponer los SNAA.
  5. Autor 1 un DomainCombiner que

    1. está construido con los SNAA;
    2. implements combine(ProtectionDomain[], ProtectionDomain[]) tal que

      1. reemplaza los dominios del argumento de la matriz (el contexto "actual") con instancias equivalentes de la implementación personalizada;
      2. luego agrega los argumentos del segundo (el contexto "asignado" o "heredado"), si corresponde, al primero tal como está; y por último
      3. 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 los getContext y checkPermission AccessController .

  6. Tras la autenticación exitosa, cree un nuevo AccessControlContext que envuelva el actual, junto con una instancia del DomainCombiner 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 de AccessController::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?