代码合同应该用于安全吗?

时间:2011-01-13 23:21:52

标签: security .net-4.0 code-contracts

您是否有任何理由不使用代码合同来执行业务规则?

假设您有一个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.
    ...
}

这两种方法有哪些优点和缺点?

1 个答案:

答案 0 :(得分:2)

我认为答案是肯定的。 代码约定是针对其失败表明代码中的严重错误的情况而设计的。他们应该是可以从错误的用户输入中恢复的东西。

Requires<T>仅适用于未使用代码约定的其他人使用的库的公共方法,或者如果您有遗留代码需要保持兼容的例外情况可以扔。

对于新代码,您应该只使用Requires,而不是Requires<T>。普通Requires默认会抛出一个无法捕获的异常,迫使您处理该问题。

此外,如果某人禁用了Code Contracts运行时检查,那么您的所有安全性都将消失!