¿Cómo puedo verificar los permisos de Shiro para la lista de elementos?

Tengo una solicitud de Hibernate que me devuelve una lista de elementos para mostrar. Necesito verificar si el usuario actual puede ver cada uno de los elementos devueltos. Puedo hacerlo algo como esto

for (Element e : elements) { 
    SecurityUtils.getSubject().hasPermission("element:view:" + e.id);   
}

pero este código generará x solicitudes a la base de datos por cada elemento. Entonces la velocidad de verificación será O(n).

¿Cómo puedo mejorar mi solución? ¿Es posible obtener la velocidad O(1)?

preguntado el 15 de mayo de 12 a las 16:05

3 Respuestas

Hay un método llamado isPermittedAll(String ...) en Asunto que regresará true si el Sujeto tiene todos los permisos.

Ver: http://shiro.apache.org/static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermittedAll%28java.lang.String...%29

Aunque, para ser honesto, no sé cuánto más eficiente es en términos de consultas de base de datos (si es que lo es).

contestado el 16 de mayo de 12 a las 04:05

Necesito filtrar elementos. Creo que si el usuario no tiene acceso a 1 elemento isPermittedAll regresará false para todos los elementos - fedor.belov

shiro admite el almacenamiento en caché, puede usar para este tipo de acciones si le gusta mucho la construcción de listas. http://shiro.apache.org/caching.html

contestado el 25 de mayo de 12 a las 11:05

Dado su ejemplo, probablemente quiera hacer lo siguiente:

String[] permissions = new String[elements.size()];

for (int i = 0; i < elements.size(); i++) {
    permissions[i] =  "element:view:" + e.id;
}

boolean[] allowed = SecurityUtils.getSubject().isPermitted(permissions);

List<Element> allowedElements = new ArrayList<Element>();

for (int i = 0; i < elements.size(); i++) {
    //1:1 match on entries in allowed to elements
    if (allowed[i]) {
        allowedElements.add(elements[i]);
    }
}

//allowedElements now contains the set of elements the user is permitted to access
return allowedElements;

El método API de asunto que utilicé está aquí: boolean[] isPermitted(String... permisos)

La desventaja de este enfoque es que efectivamente terminas iterando tu lista de elementos dos veces. Sin embargo, termina ahorrando debido al hecho de que no tiene que hacer una llamada a la base de datos por elemento.

Una cosa a tener en cuenta, su tiempo de ejecución puede cambiar dependiendo de cómo su seguridad Reino está implementado.

Respondido el 18 de junio de 13 a las 13:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.