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

Ric*_*ole 6 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.
    ...
}
Run Code Online (Sandbox Code Playgroud)

或者你可以实施安全检查作为前提条件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.
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

por*_*ges 2

我想答案是否定的。代码契约是针对其失败表明代码中存在严重错误的情况而设计的。它们应该是可以从不正确的用户输入等中恢复的东西。

Requires<T>仅用于库的公共方法,这些方法将由不使用代码契约的其他人使用,或者如果您有遗留代码需要在可以抛出的异常方面保持兼容。

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

此外,如果有人禁用代码契约运行时检查,您的所有安全性都将消失!