是否应在数据库端执行数据安全性?
我们正在为新的内部应用程序建立新的框架和开展业务的方式。我们当前的设计要求所有安全逻辑都应由我们的数据库处理,并且所有信息(我的意思是所有信息)都将通过存储过程移入和移出数据库。
从理论上讲,数据访问层从存储过程中请求信息,然后将身份验证传递给数据库。数据库确定用户的角色/权限,并决定是否执行任务(无论是检索数据还是进行更新)。
我猜这意味着更少的数据库事务。一次调用数据库。如果安全性在我们的数据访问层中,这将需要1个数据库调用来确定用户是否具有适当的权限,然后需要1个单独的数据库调用来执行操作。
我发现一个完全缺少IDE的Sql Management Studio。我主要担心的是,我们最终将不得不在存储过程中维护一些令人讨厌的业务逻辑,以实现一些非常小的性能提升。
现在,我们正在将LINQ用于我们的ORM。看起来轻巧快速,但最重要的是,它确实很容易快速开发。
维护成本是否值得提高性能?我们是否在自欺欺人地认为甚至会有明显的性能提升?还是我们只是为自己做噩梦?
我们的环境:
- 内部,非任务关键型业务应用
- C#/ ASP.NET 3.5
- Windows 2003
- MS SQL Server 2005
- 35个中型Web应用程序,约有500个用户
解决方案
回答
不要那样做最近,当"数据库专家"决定去另一家公司时,我们的经历非常糟糕。程序中所有逻辑的维护都太糟糕了!!
是的,我们将获得一些性能上的改进,但这是不值得的。实际上,在内部应用程序中,性能甚至不是什么大问题。在优质服务器上投入更多资金。它会还清。
回答
我们可以做到,但是要发展和维护它是一个巨大的痛苦。从项目中几乎所有业务逻辑都用存储过程编码的项目中的人那里获取。
为了安全起见,ASP.NET引入了用户和角色管理,因此我们可能要保存对数据库的旅行,但是那又如何呢?作为交换,处理和调试系统和验证错误变得非常烦人,因为它们必须从数据库中冒出来。
单元测试要困难得多,因为可用于单元测试存储库的框架还远远不够开发。
正确的环域驱动设计几乎是不可能的。
如果有的话,性能提升将很小。我们在这里讨论了这一点。
我建议,如果我们想保留开发人员的理智,则要竭尽全力将数据库保留为持久层
回答
不幸的是,没有"一个真实的答案"。我们必须做出的选择取决于多种因素,例如:
- 团队对给定解决方案的熟悉程度(即,如果大多数人喜欢编写SQL,则可以在数据库中,但是如果大多数人更喜欢C#,则应在代码中)
- 各方的"政治力量"
- 等等
在任何方向上都没有决定性的优势(正如我们所说的那样,性能提升是最小的),要牢记的一件事是DRY(不要重复自己)原理:不要在代码和代码中两次重复实现功能。数据库),因为让它们保持同步将是一场噩梦。选择一种解决方案并坚持下去。
回答
我的意见是,应用程序本身应处理身份验证和授权。在数据库方面,我们仅应根据需要处理数据加密。
回答
过去,我已经构建了基于存储过程的应用程序。在情况下,也许有一种方法可以将身份验证保留在数据库层,并使业务逻辑使用C#。使用视图限制数据(我们只能看到我们有权访问的行)。可以在LINQ中轻松使用这些视图,就像在表中一样。我们将更新设置为与存储过程一起发生。
这允许使用linq,C#中的业务逻辑以及数据库中的公共身份验证层来控制对数据的访问。
回答
这一切都取决于情况,最好不要走SP路由并以DDD方式进行所有操作(在代码中创建Domain模型并使用该模型)。
但是,如果数据库不仅被应用程序使用,而且被许多人使用,那么我们可能应该考虑使用Web服务。无论如何,只能通过执行业务规则的一层来访问数据库,否则我们将最终获得"脏"数据,而之后清理数据则比事先编写一些业务规则要痛苦得多。一个好的数据库应该设置检查约束和索引,因此无论我们是否喜欢,它都会有一些业务规则。
而且,如果我们必须处理数以亿计的记录,那么我们将很高兴拥有一个能为我们解决问题的优秀数据库专家。
回答
存储过程通常是安全的制胜法宝。简化应用程序与数据库之间的关系可以减少发生错误的位置。将业务逻辑连接到数据库的代码中的错误通常是安全性问题。因此,DBA不会将事情锁定到存储过程中就错了。
将应用程序锁定到存储过程的另一个好处是,应用程序堆栈的数据库连接可以将其特权锁定到特定的存储过程调用,而没有其他任何锁定。
使DBA参与我们应用程序的安全逻辑的好处是,可以在数据库中将不同的应用程序功能和角色划分为视图,因此,即使需要动态SQL和通用选择语句,SQL漏洞也会造成损害。可能会受到限制。
当然,另一方面是失去了灵活性。显然,与通过存储过程参数与DBA进行持续协商相比,ORM的开发速度更快。而且,随着对这些存储过程的压力越来越大,这些过程本身将越来越有可能诉诸于动态SQL,而动态SQL与由应用程序组成的SQL一样容易受到攻击。
这里有一个快乐的中间立场,我们应该尝试找到它。我最近从事的项目已经避免了严重的SQL注入问题,因为DBA精心配置了数据库,其连接和存储过程以使其具有"最低特权",因此任何一个数据库用户都只能访问他们所访问的内容。需要知道的。
显然,当我们在应用逻辑中编写SQL代码时,请确保我们始终使用参数化的预处理语句,正在清理输入内容,并留意国际化的输入内容(有很多方法可以说单个-引用(HTTP上的-quote),并且我们要记住当输入对于列宽而言太大时数据库的行为。
回答
恕我直言:
应用程序服务层->应用程序逻辑和验证
应用程序数据层->数据逻辑和安全性
数据库->数据一致性
迟早我们会被sproc方法所咬,我已经学到了这条很难的路。
Procs非常适合需要大量性能的单发操作,但是CRUD部分是数据层的工作