ASP.NET MVC:数据注释验证就足够了吗?
我在 ASP.NET MVC 2 中广泛使用数据注释验证。这一新功能节省了大量时间,因为我现在能够在一个地方定义客户端验证和服务器端验证。然而,当我进行一些详细测试时,我意识到如果我单独依赖数据注释验证,那么有人很容易绕过服务器端验证。例如,如果我通过使用 [Required] 属性注释属性来定义必填字段,并在表单中为该必填字段放置一个文本框,则用户可以简单地从 DOM 中删除该文本框(这可以通过 Firebug 轻松完成)现在,在控制器内部的模型绑定期间,不会在该属性上触发数据注释验证。为了确保触发“必需”验证,我可以在 ModelBinding 发生后重复验证,但随后我将重复我的验证逻辑。
大家对验证有何建议?数据注释验证就足够了吗?或者是否需要重复验证以确保在所有情况下都触发验证?
后续评论: 根据下面的答案,我似乎不能单独依赖模型绑定器和数据注释验证。由于我们得出的结论是需要额外的服务器端验证,因此我的服务层是否有一种简单的方法可以根据数据注释中定义的内容触发验证?看来这将使我们两全其美......我们不需要重复验证代码,但我们仍然会确保即使 Model Binder 不触发验证也会执行它。
我将将此后续评论作为一个单独的问题发布,因为它提出了与原始问题不同的问题。
I'm using the Data Annotation validation extensively in ASP.NET MVC 2. This new feature has been a huge time saver, as I'm now able to define both client-side validation and server-side validation in one place. However, while I was doing some detailed testing, I realized that it's quite easy for someone to bypass the server-side validation if I relied on Data Annotation validation alone. For example, if I defined a required field by annotating the property with the [Required] attribute and placed a textbox for that required field in a form, a user could simply remove the textbox from the DOM (which can easily be done through Firebug) and now the Data Annotation validation will not be triggered on that property during ModelBinding inside of a Controller. To ensure that the "required" validation is triggered, I can repeat the validation after ModelBinding happens, but then I'd be repeating my validation logic.
What is everyone's recommendation on validation? Is Data Annotation validation enough? Or does the validation need to be repeated to ensure that validations get triggered in all situations?
Follow-up comment:
Based on the answers below, it seems that I can't rely on the Model Binder and Data Annotation validation alone. Since we're concluding that additional server-side validation is required, is there an easy way for my Service layer to trigger validation based on what's been defined in the Data Annotations? It seems that this will get us the best of both words...we won't need to repeat the validation code, but we'll still ensure that the validation gets executed even if Model Binder doesn't trigger it.
I'm going to post this follow-up comment as a separate question, as it poses a different question than the original one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为要对安全性保持警惕,您应该选择将服务器验证作为优先事项,并确保这始终是您的后备措施。您的服务器验证应该在没有客户端验证的情况下工作。客户端验证更多的是针对用户体验,尽管这对您的设计至关重要,但它对于安全性来说是次要的。考虑到这一点,您会发现自己在重复验证。一个目标通常是尝试设计您的应用程序,以便尽可能集成服务器和客户端验证,以减少在服务器和客户端上验证所需的工作。但请放心,您必须两者都做。
如果绕过客户端验证(通过 DOM 操作)就避免了服务器验证(您似乎表明了这一点),那么您对此实例的服务器验证可能无法正确使用。您应该在控制器操作或服务层中再次调用服务器验证。您描述的场景不应破坏您的服务器验证。
对于您描述的场景,DataAnnotation 属性方法应该足够了。看来您只需要进行一些代码更改即可确保在提交表单时也调用服务器验证。
I think to be vigilant concerning security you should choose to you make server validation the priority and ensure that this is always your fallback. Your server validation should work without the client validation. Client validation is more for UX and tho that is paramount to your design, it is secondary to security. With this in mind you will find yourself repeating your validation. A goal is often trying to design your app so that the server and client validation can be integrated as much as possible to reduce the work required to validate on the server and the client. But be assured you must do both.
If bypassing the client validation (by means of DOM manipulation) is avoiding the server validation (which it seems you are indicating) then your server validation for this instance may not be employed appropriately. You should be invoking your server validation again in your controller action or in a service layer. The scenario you describe should not be defeating your server validation.
With the scenario you describe, the DataAnnotation attributes method should be sufficient. It seems that you simply need to make a few code changes to ensure that your server validation is invoked also when submitting the form.
我将 xVal 与 DataAnnotations 配对,并编写了自己的操作过滤器,用于检查任何实体类型参数以进行验证。因此,如果回发中缺少某些字段,该验证器将填充 ModelState 字典,从而使模型无效。
先决条件:
IObjectValidator
接口,该接口声明Validate()
方法。ValidateBusinessObjectAttribute
操作过滤器代码:
我的控制器操作定义如下:
I paired xVal with DataAnnotations and have written my own Action filter that checks any Entity type parameters for validation purposes. So if some field is missing in the postback, this validator will fill ModelState dictionary hence having model invalid.
Prerequisites:
IObjectValidator
interface which declaresValidate()
method.ValidateBusinessObjectAttribute
Action filter code:
My controller action is defined like this then:
DataAnnotation 当然是不够的。我还广泛使用它来预先验证对域模型的调用,以获得更好的错误报告并尽早失败。
不过,您可以自己调整 DataAnnotation 模型,以确保必须发布带有 [Required] 的属性。 (今天晚些时候将跟进代码)。
更新
获取 DataAnnotations Model Binder 的源代码并在 DataAnnotationsModelBinder.cs 中找到此行,
将其更改为
The DataAnnotation is certainly not enough. I use it extensively also to pre-validate my calls to the domain model to get better error reporting and fail as early as possible.
You can however tweak the DataAnnotation Model yourself to ensure properties with [Required] MUST be posted. (will follow up with code later today).
UPDATE
Get the source for DataAnnotations Model Binder and find this line in DataAnnotationsModelBinder.cs
Change it to
我通过复制 xVal 的 DataAnnotationsRuleProvider 和 Microsoft 的 DataAnnotationsModelBinder(以及 Martijn 的评论)中的模式,为 MVC 1.0 编写了自己的 ValidationService。服务接口如下:
该服务是一个验证运行程序,它遍历它接收的对象实例的属性树,并实际执行它在每个属性上找到的验证属性,当属性无效时构建 ErrorInfo 对象列表。 (我会发布整个源代码,但它是为客户端编写的,我还不知道我是否有权这样做。)
然后,您可以在准备好时让控制器、业务逻辑服务显式调用验证,而不是完全依赖模型绑定器进行验证。
您还应该注意其他几个陷阱:
注释实际上并没有做任何事情
数据类型验证,所以你需要
编写一个新属性
实际上使用 xVal 正则
表达式(或其他东西)
执行服务器端数据类型
验证。
用于创建客户端的属性
验证,所以你可能想要
进行一些更改以变得更加强大
客户端验证。
如果我被允许并且有时间,我会尝试提供更多资源......
I wrote my own ValidationService for MVC 1.0 by copying patterns from both xVal's DataAnnotationsRuleProvider and Microsoft's DataAnnotationsModelBinder (and Martijn's comments). The service interface is below:
The service is a validation runner that walks the property tree of the object instance it receives and actually executes the validation attributes that it finds on each property, building a list of ErrorInfo objects when attributes are not valid. (I'd post the whole source but it was written for a client and I don't know yet if I'm authorized to do so.)
You can then have your controllers, business logic services explicitly invoke validation when you are ready, rather than relying exclusively on the model binder for validation.
There are a couple of other pitfalls that you should be aware of:
annotations doesn't actually do any
data type validation, so you'll need
to write a new attribute that
actually uses xVal regular
expressions (or something else) to
perform server-side data type
validation.
properties to create client-side
validation, so you may want to make
some changes there to get more robust
client-side validation.
If I am allowed and have time, I will try to make more source available...
请参阅 codeProject 使用数据注释进行服务器端输入验证< /a>
See codeProject Server-side Input Validation using Data Annotations