应该在数据库端执行数据安全吗?

时间:2008-09-11 05:21:31

标签: sql security stored-procedures

我们正在为新的内部应用设置新的框架和业务方式。我们当前的设计规定所有安全逻辑都应由我们的数据库处理,所有信息(我的意思是所有信息)都将通过存储过程进出数据库。

理论上,数据访问层从存储过程请求信息并将身份验证传递给数据库。数据库确定用户的角色/权限,并决定是否执行任务(无论是检索数据还是进行更新)。

我想这意味着更少的数据库事务。一次调用数据库。如果安全性在我们的数据访问层中,则需要1次数据库调用以确定用户是否具有适当的权限,然后单独的数据库调用以执行操作。

我认为SQL管理工作室完全缺乏IDE。我主要担心的是,我们最终必须在存储过程中维护一些讨厌的业务逻辑,以获得非常小的性能提升。

现在,我们正在为我们的ORM使用LINQ。它似乎轻快,但最重要的是,它很容易快速发展。

维护成本是否值得性能提升?我们是否在愚弄自己,以为甚至会有明显的性能提升?或者我们只是为自己制造噩梦?

我们的环境:

  • 内部非关键业务应用
  • C#/ ASP.NET 3.5
  • Windows 2003
  • MS SQL Server 2005
  • 35个中型网页应用,约有500名用户

8 个答案:

答案 0 :(得分:8)

不要那样做。当“数据库大师”决定去另一家公司时,我们最近遇到了非常糟糕的经历。维护程序中的所有逻辑真是太可怕了!!

是的,你会有一些性能提升,但这不值得。事实上,性能在内部应用中甚至不是一个大问题。在优质服务器上投入更多资金。它会得到回报。

答案 1 :(得分:3)

不幸的是,没有“一个真正的答案”。您必须做出的选择取决于多种因素,例如:

  • 团队对给定解决方案的熟悉程度(即如果他们中的大多数人习惯于编写SQL,它可以在数据库中,但是如果他们中的大多数人对C#更熟悉,那么它应该在代码中)
  • 各方的“政治权力”

在任何方向都没有决定性的优势(正如你所说的性能提升很小),要记住的一件事就是DRY(不要重复自己)原则:不要重新实现两次功能(在代码和数据库),因为保持它们同步将是一场噩梦。选择一种解决方案并坚持下去。

答案 2 :(得分:2)

你可以做到这一点,但是发展反对和维持是一个巨大的痛苦。从项目中的某个人那里获取它,几乎所有业务逻辑都在存储过程中编码。

为了安全起见,ASP.NET将用户和角色管理融入其中,以便您可以节省数据库的访问但是又如何呢?作为交换,处理和调试系统和验证错误变得更加烦人,因为它们必须从数据库中冒出来。

单元测试要困难得多,因为可用于单元测试的框架很少发展。

正确的oop和域驱动设计几乎不在窗外。

如果有的话,性能提升很小。我们谈到了here

我建议如果你想以开发人员的身份保存自己的理智,那么你就要坚持不懈地将数据库作为持久层保护

答案 3 :(得分:2)

IMHO:

应用服务层 - >应用逻辑和验证
应用程序数据层 - >数据逻辑和安全性 数据库 - >数据一致性

迟早会被你的方法所困扰,我已经很难学会了这一点 Proc非常适合需要大量性能的一次性操作,但CRUD部分是数据层工作

答案 4 :(得分:1)

这一切都取决于你的情况,最好不要去SP路线并以DDD方式做所有事情(在代码中制作域模型并使用它)。

但是,如果您的数据库不仅被您的应用程序使用,而且被许多人使用,那么您应该考虑使用Web服务。无论如何,数据库只能通过一个强制执行业务规则的层访问,否则您将最终得到“脏”数据并在之后清理数据比预先编写一些业务规则要大得多。一个好的数据库应该设置检查约束和索引,因此无论你喜不喜欢它都会有一些业务规则。

如果你必须处理数百万和数十亿的记录,你会很高兴有一个好的DB人为你解决问题。

答案 5 :(得分:1)

存储过程通常是安全的胜利。简化应用程序与数据库之间的关系可以减少可能出错的地方数量;将业务逻辑与数据库接口的代码中的错误往往是安全问题。因此,您的DBA将内容锁定到存储过程并没有错。

将应用程序锁定到存储过程的另一个好处是,应用程序堆栈的数据库连接可以将其权限锁定到特定的存储过程调用,而不是其他任何操作。

让DBA参与应用程序的安全逻辑的一个好处是,可以将不同的应用程序功能和角色在数据库中分区到视图,这样即使需要动态SQL和泛型select语句,也会造成损坏。可以约束SQL漏洞。

这方面的另一面当然是失去了灵活性。与使用DBA对存储过程参数的持续协商相比,开发ORM显然会更快。而且,随着对这些存储过程的压力越来越大,程序本身越来越倾向于采用动态SQL,这与应用程序组成的SQL一样容易受到攻击。

这里有一个幸福的中间地带,你应该试着找到它。我最近研究过的项目是从非常可怕的SQL注入问题中解决的,因为DBA已经仔细配置了数据库,它的连接以及“最小权限”的存储过程,因此任何一个数据库用户都只能访问它们需要知道。

显然,当您在应用程序逻辑中编写SQL代码时,请确保您始终使用参数化预准备语句,您正在清理您的输入,您注意到国际化输入(有很多很多方法)通过HTTP说单引号,并且当输入对于列宽太大时,你会注意到数据库的行为。

答案 6 :(得分:0)

我的意见是应用程序本身应该处理身份验证和授权。在数据库方面,您应该只根据需要处理数据加密。

答案 7 :(得分:0)

我过去已经构建了基于存储过程的应用程序。在您的情况下,可能有一种方法可以在数据库层保持身份验证,并在C#中使用您的业务逻辑。使用视图来限制数据(您只能看到您有权访问的行)。这些视图可以在LINQ中使用,与表格相同。您可以使用存储过程设置更新。

这允许linq,C#中的业务逻辑以及数据库中用于控制对数据的访问的公共身份验证层。