Должны ли кодовые контракты использоваться для безопасности? - PullRequest
6 голосов
/ 14 января 2011

Существуют ли причины, по которым вы не будете использовать кодовые контракты для обеспечения соблюдения бизнес-правил?

Представьте, что у вас есть класс 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 Ответ

2 голосов
/ 14 января 2011

Я думаю, что ответ - нет. Кодовые контракты предназначены для сценариев, в которых их ошибка указывает на серьезную ошибку в коде . Они должны , а не быть чем-то, что может быть восстановлено, например, неправильным вводом пользователем.

Requires<T> предназначен для использования только в открытых методах библиотеки, которые будут использоваться другими, не использующими кодовые контракты, или если у вас есть устаревший код, который должен оставаться совместимым с точки зрения того, какие исключения он может генерировать .

Для нового кода вы должны использовать только Requires, а не Requires<T>. Обычная Requires по умолчанию генерирует неуловимое исключение, чтобы заставить вас решить проблему.

Кроме того, если кто-то отключит проверку времени выполнения контрактов, вся ваша безопасность исчезнет!

...