Поделиться через


Общие сведения о уровне защиты

Свойство ProtectionLevel найдено во многих различных классах, таких как ServiceContractAttribute классы и OperationContractAttribute классы. Свойство определяет, как защищена часть (или целое) сообщения. В этом разделе описывается функция Windows Communication Foundation (WCF) и его работа.

Инструкции по настройке уровня защиты см. в разделе "Практическое руководство. Задание свойства ProtectionLevel".

Замечание

Уровни защиты можно задать только в коде, а не в конфигурации.

Основы

Чтобы понять функцию уровня защиты, применяются следующие основные инструкции:

  • Для любой части сообщения существуют три основных уровня защиты. Свойство (где бы оно ни встречалось) устанавливается в одно из значений ProtectionLevel перечисления. В порядке возрастания защиты они включают:

    • None.

    • Sign. Защищенная часть имеет цифровую подпись. Это гарантирует обнаружение любых изменений с защищенной частью сообщения.

    • EncryptAndSign. Часть сообщения шифруется, чтобы обеспечить конфиденциальность перед подписью.

  • Требования к защите можно задать только для данных приложения с помощью этой функции. Например, WS-Addressing заголовки являются данными инфраструктуры и, следовательно, не подвержены влиянию ProtectionLevel.

  • Если режим безопасности установлен на Transport, все сообщение защищается транспортным механизмом. Поэтому установка отдельного уровня защиты для разных частей сообщения не влияет.

  • Разработчик ProtectionLevel может установить минимальный уровень, которому должна соответствовать привязка. При развертывании службы фактическая привязка, указанная в конфигурации, может или не поддерживает минимальный уровень. Например, по умолчанию BasicHttpBinding класс не предоставляет безопасность (хотя он может быть включен). Поэтому использование его с контрактом, который имеет любой другой параметр, кроме None, приведет к возникновению исключения.

  • Если служба требует, чтобы минимальное значение ProtectionLevel для всех сообщений было Sign, клиент (возможно, созданный технологией, отличной от WCF), может шифровать и подписывать все сообщения (что превышает минимальное требование). В этом случае WCF не будет вызывать исключение, так как клиент сделал больше минимального. Обратите внимание, что приложения WCF (службы или клиенты) не будут чрезмерно защищать часть сообщения, если это возможно, но будут соответствовать минимальному уровню. Кроме того, обратите внимание, что при использовании Transport в качестве режима безопасности транспорт может чрезмерно защитить поток сообщений, так как он по сути не может защититься на более детальном уровне.

  • Если вы явно задали ProtectionLevel в Sign или EncryptAndSign, тогда необходимо использовать привязку с включенной безопасностью, иначе будет вызвано исключение.

  • Если выбрать привязку, которая обеспечивает безопасность, и вы не задаете ProtectionLevel свойство в любом месте контракта, все данные приложения будут зашифрованы и подписаны.

  • Если выбрана привязка, в которой безопасность не включена (например, безопасность класса BasicHttpBinding отключена по умолчанию) и ProtectionLevel не задан явным образом, данные приложения не будут защищены.

  • Если вы используете привязку, которая применяет безопасность на уровне транспорта, все данные приложения будут защищены в соответствии с возможностями транспорта.

  • Если вы используете привязку, которая применяет безопасность на уровне сообщения, данные приложения будут защищены в соответствии с уровнями защиты, заданными в контракте. Если уровень защиты не указан, все данные приложения в сообщениях будут зашифрованы и подписаны.

  • Его ProtectionLevel можно задать на разных уровнях области видимости. Существует иерархия, связанная с области, которая описана в следующем разделе.

Определение области:

Установка высшего ProtectionLevel API задает уровень для всех уровней под ним. ProtectionLevel Если задано другое значение на более низком уровне, все API ниже этого уровня в иерархии теперь будут сбрасываться на новый уровень (API над ним, однако, по-прежнему будут затронуты самым верхним уровнем). Иерархия выглядит следующим образом. Атрибуты на одном уровне — равнозначные.

Программирование уровня защиты

Чтобы программировать ProtectionLevel в любой точке иерархии, просто задайте для свойства соответствующее значение при применении атрибута. Примеры см. в разделе "Практическое руководство. Настройка свойства ProtectionLevel".

Замечание

Настройка свойства для ошибок и контрактов сообщений требует понимания того, как работают эти функции. Дополнительные сведения см. в разделе "Практическое руководство. Настройка свойства ProtectionLevel и использование контрактов сообщений".

WS-Addressing зависимость

В большинстве случаев использование средства служебной программы метаданных ServiceModel (Svcutil.exe) для создания клиента гарантирует, что контракты клиента и службы идентичны. Однако, казалось бы, идентичные контракты могут вызвать у клиента исключение. Это происходит всякий раз, когда привязка не поддерживает спецификацию WS-Addressing и несколько уровней защиты указываются в контракте. Например, BasicHttpBinding класс не поддерживает спецификацию или если вы создаете пользовательскую привязку, которая не поддерживает WS-Адресацию. Эта ProtectionLevel функция зависит от спецификации WS-Addressing, чтобы включить различные уровни защиты в одном контракте. Если привязка не поддерживает спецификацию WS-Addressing, все уровни будут иметь одинаковый уровень защиты. Уровень эффективной защиты для всех областей контракта будет установлен на самый сильный уровень защиты, используемый в контракте.

Это может привести к возникновению проблемы, которую трудно отлаживать на первый взгляд. Можно создать контракт клиента (интерфейс), включающий методы для нескольких служб. То есть один и тот же интерфейс используется для создания клиента, который взаимодействует со многими службами, а один интерфейс содержит методы для всех служб. Разработчик должен учитывать этот редкий сценарий, чтобы вызывать только те методы, которые применимы для каждого конкретного сервиса. Если привязка является классом BasicHttpBinding , невозможно поддерживать несколько уровней защиты. Однако служба, отвечающая клиенту, может реагировать на клиента с более низким уровнем защиты, чем требуется. В этом случае клиент вызовет исключение, так как ожидает более высокий уровень защиты.

Пример кода иллюстрирует эту проблему. В следующем примере показана служба и контракт клиента. Предположим, что привязка является элементом <basicHttpBinding>. Поэтому все операции контракта имеют одинаковый уровень защиты. Этот уровень универсальной защиты определяется как максимальный уровень защиты во всех операциях.

Контракт службы:

[ServiceContract()]
public interface IPurchaseOrder
{
    [OperationContract(ProtectionLevel = ProtectionLevel.Sign)]
    int Price();
}
<ServiceContract()> _
Public Interface IPurchaseOrder
    <OperationContract(ProtectionLevel:=ProtectionLevel.Sign)> _
    Function Price() As Integer
End Interface

В следующем коде показан интерфейс контракта клиента. Обратите внимание, что он включает Tax метод, который предназначен для использования с другой службой:

[ServiceContract()]
public interface IPurchaseOrder
{
    [OperationContract()]
    int Tax();

    [OperationContract(ProtectionLevel = ProtectionLevel.Sign)]
    int Price();
}
<ServiceContract()> _
Public Interface IPurchaseOrder
    <OperationContract()> _
    Function Tax() As Integer

    <OperationContract(ProtectionLevel:=ProtectionLevel.Sign)> _
    Function Price() As Integer
End Interface

Когда клиент вызывает Price метод, он создает исключение при получении ответа от службы. Это происходит из-за того, что клиент не указывает ProtectionLevel на ServiceContractAttribute, поэтому клиент использует по умолчанию EncryptAndSign для всех методов, включая метод Price. Однако служба возвращает значение, используемое на Sign уровне, так как контракт службы определяет один метод с заданным уровнем Signзащиты. В этом случае клиент выдает ошибку при проверке ответа от службы.

См. также