java - example - dbcp2 maxtotal
Envoltura segura de una piscina de conexión (4)
Estoy tratando de implementar seguridad a nivel de fila para que nuestra aplicación pueda imponer un control de acceso más estricto.
Una de las tecnologías que estamos investigando es la base de datos privada virtual de Oracle, que permite la seguridad a nivel de fila básicamente incrementando todas las consultas contra tablas específicas con un predicado de cláusula where
. Dado que estamos en un entorno web, necesitamos configurar un contexto especial dentro de Oracle, dentro de un solo hilo de solicitud. Utilizamos la agrupación de conexiones con una cuenta de servicio.
Comencé a estudiar Eclipse Link y Hibernate. Eclipse Link parece tener events que encajan perfectamente en este modelo.
Esto nos implicaría migrar de hibernación, lo cual no es un problema, pero entonces estaríamos atados a EL por estos eventos.
Oracle parece implicar que se implementan en el nivel de origen de datos en el producto de Web Logic .
El contexto se establece y borra con el código fuente de datos de WebLogic.
Pregunta: ¿Es más apropiado hacer esto en el nivel de DataSource con algunas series de eventos? ¿Cuáles son los eventos o métodos a los que debería prestar más atención también?
Pregunta agregada: ¿Cómo extender un grupo de conexiones para inicializar de forma segura un contexto de Oracle con algunos datos personalizados? Estoy investigando en Apache, y parece que la extensión de BasicDataSource no me da acceso a nada que me permita limpiar la conexión cuando Spring termine.
Necesito configurar una conexión y limpiar una conexión al salir / ingresar al conjunto de conexiones. Espero una implementación que sea tan simple, que nadie pueda estropearla rompiendo un delicado equilibrio de productos.
- Specifically we are currently using Apache Commons DBCP Basic Data Source
Esto nos permitiría utilizar varias formas de conectarnos a la base de datos y seguir aplicando nuestra seguridad. Pero no veo un gran ejemplo o conjunto de eventos con los que trabajar, y nunca es una buena idea dar marcha a mi propio ciclo de vida de seguridad .
Eventualmente resolví mi problema extendiendo algunos de los componentes de Apache.
Primero extendí org.apache.commons.pool.impl.GenericObjectPool
y borrowObject()
y returnObject()
. Sabía el tipo de objetos en el grupo ( java.sql.Connection
) para poder lanzarlos y trabajar con ellos de forma segura.
Como para mi caso estaba usando Oracle VPD, pude establecer información en el contexto de la aplicación. Te recomiendo leer sobre eso en más profundidad. Es un poco complicado y hay muchas opciones diferentes para ocultar o compartir datos en diversos contextos y en los nodos de RAC. Start
En esencia, lo que hice fue generar un nonce y usarlo para instanciar una sesión dentro de oracle, y luego establecer el nivel de acceso del usuario a una variable en esa sesión, que la política de VPD de Oracle leería y usaría para hacer el nivel de fila. filtración.
Instalé y destruí esa información en mi borrowObject()
y returnObject()
El SQL que ejecuté era algo como esto:
CallableStatement callStat =
conn.prepareCall("{call namespace.cust_ctx_pkg.set_session_id(" + Math.random() + ")}");
callStat.execute();
Tenga en cuenta que math.random()
no es una buena fuente.
Lo siguiente fue simplemente extender org.apache.commons.dbcp.BasicDataSource
y configurar mi grupo de objetos reemplazando createConnectionPool()
. Tenga en cuenta que la forma en que lo hice deshabilitó algunas funciones que no necesitaba, por lo que es posible que tenga que volver a escribir más o menos que yo.
Obtendrá un mejor control al utilizar una de las otras fuentes de datos de Commons DBCP. El básico es solo eso: básico :) Los que se encuentran en el paquete org.apache.commons.dbcp.datasources le brindan un control más detallado.
Puede probar cualquier mecanismo de seguridad a nivel de objeto por simplicidad, como Spring Security ACL.
Usted querrá hacer esto en la capa de aplicación. Usted querrá un enlace de pre-confirmación y un enlace de lectura posterior.
El enlace de confirmación previa se utiliza para garantizar que los datos del cliente estén siendo presentados por un usuario autorizado para modificar esos datos. Esto evita que un usuario no autorizado sobrescriba datos a los que no debería poder acceder.
No es intuitivo, pero el enlace de lectura posterior se usa para evitar que el cliente acceda a los datos que el usuario no debería poder ver. Esto sucede después de la vista porque se aplica en la capa de aplicación, no en la capa de datos. La aplicación no tiene forma de saber si la persona que llama tiene permiso para acceder a los datos hasta que se haya recuperado de la capa de datos. En el enlace de lectura posterior, evalúa la credencial en cada fila devuelta contra la credencial del usuario que inició sesión para determinar si se permite o no el acceso. Si se deniega el acceso en cualquier fila, se generará una excepción y los datos no se devolverán al cliente.
La seguridad de nivel de aplicación realizada de esta manera requiere que tenga una manera de conectar cada fila de una tabla a un permiso / rol requerido para acceder a ella y una forma de evaluar los permisos de un usuario en el servidor en tiempo de ejecución.
Espero que ayude.