对 Linq-to-sql 实体 load() 进行多租户支持检查
我正在编写一个 aspx 应用程序,它将在公共 SQL Server 数据库中托管 1000 个小客户。所有实体都将通过 Linq-To-Sql 创建和加载。
代理键(标识列)将在整个架构中用于所有表关系,因此从根客户对象开始,我应该能够使用常规 Linq 查询(SQL 连接)导航到特定客户的独占数据集。
然而,从安全角度来看,上述内容有点脆弱,因此我希望添加额外的租赁检查层作为安全保障。我的实体模型中的所有实体都将具有非索引 int TenantId 字段。
我正在从性能角度寻找对此解决方案的批评意见。
public partial class MyLinqEntity
partial void OnLoaded() // linq-to-sql extensibility function
{
if ( this.TennantId != HttpContext.Current.Session["tenantId"] )
throw new ApplicationException("Logic error, LINQ query crossed tenantId data boundary");
}
partial void OnCreated() // linq-to-sql extensibility function
{
this.TennantId = HttpContext.Current.Session["tenantId"] );
}
I am writing an aspx application that will host 1000's of small customers in a communal SQL Server database. All entities will be created and loaded via Linq-To-Sql.
Surrogate keys (identity columns) will be used throughout the schema for all table relationships and so starting with a root customer object I should be able to navigate to exclusive sets of data for a particular customer using regular Linq queries (SQL joins).
However from a security standpoint the above is a bit fragile so I wish to add an extra layer of tenancy check as a security backstop. All entities in my entity model will have a non-indexed int TenantId field.
I am looking for critical comments about this solution from a performance perspective.
public partial class MyLinqEntity
partial void OnLoaded() // linq-to-sql extensibility function
{
if ( this.TennantId != HttpContext.Current.Session["tenantId"] )
throw new ApplicationException("Logic error, LINQ query crossed tenantId data boundary");
}
partial void OnCreated() // linq-to-sql extensibility function
{
this.TennantId = HttpContext.Current.Session["tenantId"] );
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
抱歉,这主要是随机的想法……
我不喜欢所有依赖于 HttpContext 的对象。
我也不知道在会话中查找每个对象是否足够快。我认为您的速度不会有问题,因为数据库查找通常比您在处理过程中执行的任何操作都要慢得多。
我倾向于使用依赖项注入框架来自动创建一个具有会话范围的对象来进行检查。但是,如果您在其他地方不需要依赖注入框架,那么这就太过分了。
由于所有数据库行都将具有tenantId列,我希望您可以将检查移至linq-to-sql“行读取回调”中,这样您就不必将其放入每个对象中。我不知道“linq-to-sql”,但是我希望您可以连接到它的查询创建框架,并向所有数据库查询添加“where teneded = xx”。
在所有采石场中设置“wheretened = xx”将允许在客户需要时对数据库进行分区,从而使“表扫描”等更便宜。
Sorry this is mostly random thoughts….
I do not like all the objects depending on HttpContext.
Also I don’t know if looking in the session for each object is fast enough. I think you will be OK on speed, as a database lookup will normally be a lot slower then anything you do in process.
I would tend to use a dependency injection framework to auto create an object that has session scope to do the check. However if you don’t have a need for a dependency injection framework elsewhere this will be over kill.
As all your database rows will have tenantId column, I hope you can move the check into a linq-to-sql “row read callback”, so you don’t have to put it into each object. I don’t know “linq-to-sql”, however I expect you could hook into it’s query creation framework and add a “where tenanted = xx” to all database queries.
Having a “where tenanted = xx” in all quarries will let partition the database if needed by customer, so making “table scans” etc cheaper.