Estoy tratando de crear un marco ACL flexible en Java para mi aplicación.
Muchos marcos de ACL se basan en una lista blanca de reglas, donde una regla tiene la forma de propietario: acción: recurso . Por ejemplo,
- "JOHN puede VER el recurso FOOBAR-1"
- "MARY puede VER el recurso FOOBAR-1"
- "MARY puede EDITAR el recurso FOOBAR-1"
Esto es atractivo porque las reglas se pueden serializar / persistir fácilmente en una base de datos. Pero mi aplicación tiene una lógica empresarial compleja. Por ejemplo,
- "Todos los usuarios en el departamento 1 con más de 5 años de antigüedad pueden VER el recurso FOOBAR-1, de lo contrario no están autorizados"
- "Todos los usuarios del departamento 2, si la fecha es posterior al 15/03/2016, pueden VER el recurso FOOBAR-2, de lo contrario no están autorizados"
Pensándolo bien, sería una pesadilla diseñar un esquema de base de datos que pudiera manejar reglas infinitamente complejas como estas. Por lo tanto, parece que tendría que "hornearlos" en la aplicación compilada, evaluarlos para cada usuario y luego producir propietario: acción: reglas de recursos como resultado de la evaluación. Quiero evitar incluir la lógica en la aplicación compilada.
Entonces, estaba pensando en representar una regla en forma de predicado : acción: recurso , donde el predicado es una expresión booleana que determina si un usuario está permitido. El predicado sería una cadena de una expresión de JavaScript que podría ser evaluada por el motor Rhino de Java. Por ejemplo,
return user.getDept() == 1 && user.seniority > 5;
Al hacerlo, los predicados podrían fácilmente persistir en la base de datos.
¿Es esto inteligente ? ¿Es esto descuidado ? ¿Esto es un truco ? ¿Está sobre-diseñado ? ¿Es esto seguro (aparentemente, Java puede proteger el motor Rhino).