应该使用代码合约来保证安全吗?
您有什么理由不使用代码契约来执行业务规则吗?
假设您有一个 User
类,它代表系统的单个用户并定义可以针对其他用户执行的操作。您可以编写这样的 ChangePassword
方法...
public void ChangePassword(User requestingUser, string newPassword)
{
Contract.Requires<ArgumentNullException>(requestingUser);
Contract.Requires<ArgumentNullException>(newPassword);
// Users can always change their own password, but they must be an
// administrator to change someone else's.
if (requestingUser.UserId != this.UserId &&
!requestingUser.IsInRole("Administrator"))
throw new SecurityException("You don't have permission to do that.");
// Change the password.
...
}
或者您可以使用 Contract.Requires
来实现安全检查作为前提...
public void ChangePassword(User requestingUser, string newPassword)
{
Contract.Requires<ArgumentNullException>(requestingUser != null);
Contract.Requires<ArgumentNullException>(newPassword != null);
// Users can always change their own password, but they must be an
// administrator to change someone else's.
Contract.Requires<SecurityException>(
requestingUser.UserId == this.UserId ||
!requestingUser.IsInRole("Administrator"),
"You don't have permission to do that.");
// Change the password.
...
}
这些的优点和缺点是什么两种方法?
Are there any reasons why you wouldn't use Code Contracts to enforce business rules?
Imagine you have a User
class that represents a single user of a system and defines actions that can be performed against other users. You could write a ChangePassword
method like this...
public void ChangePassword(User requestingUser, string newPassword)
{
Contract.Requires<ArgumentNullException>(requestingUser);
Contract.Requires<ArgumentNullException>(newPassword);
// Users can always change their own password, but they must be an
// administrator to change someone else's.
if (requestingUser.UserId != this.UserId &&
!requestingUser.IsInRole("Administrator"))
throw new SecurityException("You don't have permission to do that.");
// Change the password.
...
}
Or you could implement the security check as a precondition with Contract.Requires
...
public void ChangePassword(User requestingUser, string newPassword)
{
Contract.Requires<ArgumentNullException>(requestingUser != null);
Contract.Requires<ArgumentNullException>(newPassword != null);
// Users can always change their own password, but they must be an
// administrator to change someone else's.
Contract.Requires<SecurityException>(
requestingUser.UserId == this.UserId ||
!requestingUser.IsInRole("Administrator"),
"You don't have permission to do that.");
// Change the password.
...
}
What are the advantages and disadvantages of these two methods?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想答案是否定的。
代码合约是针对其失败表明代码中存在严重错误的场景而设计的。它们不应该是可以从不正确的用户输入等中恢复的东西。
Requires
仅用于库的公共方法,该方法将由不使用代码契约的其他人使用,或者如果您有遗留代码需要在以下方面保持兼容:它可以抛出什么异常。对于新代码,您应该仅使用
Requires
,而不是Requires
。 PlainRequires
默认情况下会抛出一个无法捕获的异常,以强制您处理问题。此外,如果有人禁用代码契约运行时检查,您的所有安全性都将消失!
I think the answer is no.
Code Contracts are designed for scenarios where their failure indicates a serious bug in the code. They should not be something that can be recovered from such as incorrect user input.
Requires<T>
is meant to be used only on public methods of a library that will be consumed by others who are not using Code Contracts, or if you have legacy code that needs to remain compatible in terms of what exceptions it can throw.For new code, you should only be using
Requires
, notRequires<T>
. PlainRequires
throws an uncatchable exception by default, to force you to deal with the problem.Furthermore, if someone disables Code Contracts runtime checking, all your security will disappear!