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

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

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

Примечание

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

Основные сведения

Ниже приведены основные сведения о функции уровня защиты.

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

    • None.

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

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

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

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

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

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

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

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

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

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

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

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

Scoping

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

Программирование ProtectionLevel

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

Примечание

Чтобы задать данное свойство в контрактах сбоев и сообщений, необходимо понимать работу этих функций. Дополнительные сведения см. в разделе инструкции. Установка свойства ProtectionLevel и использование контрактов сообщений.

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

В большинстве случаев использование средства служебной программы метаданных ServiceModel (Svcutil.exe) для создания клиента гарантирует идентичность клиентских и сервисных контрактов. Однако одинаковые на первый взгляд контракты могут приводить к вызову клиентом исключения. Это происходит всякий раз, когда привязка не поддерживает спецификацию WS-Addressing и в контракте определено несколько уровней защиты. Например, это происходит при использовании класса BasicHttpBinding, не поддерживающего данную спецификацию, или при создании пользовательской привязки, которая не поддерживает WS-Addressing. Чтобы в одном контракте разрешить разные уровни защиты, функция 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. В этом случае при проверке ответа от службы клиент вызовет ошибку.

См. также раздел