2008-10-04 13 views
10

He estado tratando de considerar cómo se podría implementar Row Level Security con Entity Framework. La idea es tener un agnóstico de base de datos que ofrezca métodos para restringir las filas provenientes de ObjectContext.Seguridad de nivel de fila con Entity Framework

Algunas de mis ideas iniciales han implicado la modificación de las clases parciales creadas por la herramienta EDMGEN y que han ofrecido un apoyo limitado. Los usuarios aún pueden sortear esta solución utilizando sus propias declaraciones eSQL y un QueryObject.

He estado buscando una solución integral que existiría por encima de los proveedores de bases de datos para que permanezca en el agnóstico.

Respuesta

10

Claro que puedes hacerlo. Lo importante es bloquear el acceso directo al contexto del objeto (evitando que los usuarios construyan su propio ObjectQuery), y en su lugar darle al cliente una puerta de enlace más estrecha dentro de la cual acceder y mutar las entidades. Lo hacemos con el Entity Repository pattern. Puede encontrar un example implementation of this pattern for the entity framework in this blog post. Nuevamente, la clave es bloquear el acceso al contexto del objeto. Tenga en cuenta que la clase de contexto del objeto es parcial. Por lo tanto, debe poder evitar los medios "no autorizados" de instanciarlo, es decir, fuera de su conjunto de repositorio.

Sin embargo, hay sutilezas a considerar. Si implementa seguridad de vista a nivel de fila en un tipo de entidad determinado a través del patrón de repositorio, entonces debe considerar otros medios por los cuales un cliente podría acceder a las mismas entidades. Por ejemplo, a través de las relaciones de navegación. Es posible que deba establecer algunas de esas relaciones como privadas, lo que puede hacer en su modelo. También tiene la opción de specifying a custom query o un procedimiento almacenado para cargar/guardar entidades. Los procedimientos almacenados tienden a ser específicos del servidor de bases de datos, pero el SQL se puede escribir de forma genérica.

Si bien no estoy de acuerdo con que esto no pueda hacerse con Entity Framework, estoy de acuerdo con los comentarios "hazlo en el servidor de bases de datos" en la medida en que debas implementar defense in depth.

+0

Tenga en cuenta que SQL Azure y SQL Server 2016 ahora se han integrado en Row Level Security y se pueden usar con Entity Framework. Aquí hay un tutorial https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-entity-framework-row-level-security/ –

2

El lugar donde agrega seguridad realmente depende de contra quién intenta protegerlo.

Si, por ejemplo, estaba protegiendo un sitio web, entonces agregar el filtrado en el contexto sería suficiente, porque los "usuarios" en este caso están en el sitio web. No tienen más remedio que pasar por su contexto, ya que escribiría la aplicación completamente contra el contexto.

En su caso, parece que los "usuarios" contra los que intenta protegerse son los desarrolladores. Eso es bastante más difícil. Si los desarrolladores no tienen acceso para realizar modificaciones en la base de datos, entonces deberá poner la seguridad en el nivel de la base de datos. Ninguna cantidad de acceso de eSQL podrá moverse por la base de datos diciendo "no".

1

Lo que intentas lograr es, por definición, imposible.

Si la aplicación de base de datos subyacente (SQL Server, Oracle, lo que sea) no maneja la seguridad de forma explícita, las herramientas estándar como SQL Management Studio soplarán.

Lo mejor que puede hacer es hacer cumplir la seguridad de nivel de fila por los usuarios de la aplicación SÓLO si esos usuarios no tienen acceso a la base de datos a través de otro mecanismo.

0

he encontrado una manera de hacerlo utilizando Postgres y una extensión llamada Veil. Realmente funciona (diseñado para) usar Views para todas las operaciones (seleccionar, actualizar, eliminar, insertar) y verificar los permisos en las cláusulas WHERE. Pero Veil solo agrega las matemáticas para administrar eficientemente la información de los permisos en la memoria en lugar de consultarla en todo momento. Así que con Veil, aunque se conecte directamente a DBMS, solo tiene acceso a nivel de fila otorgado por usted.

Modifico mi estilo con velo de alguna manera, por ejemplo, comencé a usar Triggers en lugar de Views para aplicar restricciones de permisos.

Te recomiendo que estudies esta solución e intentes aplicar su lógica aquí.

es decir: Realiza una consulta select * from table y obtiene exactamente lo que intenta (nivel de fila hablando).