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


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

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

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

Aa347692.note(ru-ru,VS.100).gifПримечание
Уровни защиты можно задавать только в коде, а не в конфигурации.

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

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

  • Для любой части сообщения существуют три базовых уровня защиты. Для свойства (где бы оно ни появлялось) задается одно из значений перечисления 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, расположенные выше этого уровня, остаются под влиянием самого верхнего уровня). Иерархия имеет представленный ниже вид. Атрибуты на одном и том же уровне являются одноранговыми.

ServiceContractAttribute

      OperationContractAttribute

            FaultContractAttribute

            MessageContractAttribute

                     MessageHeaderAttribute

                     MessageBodyMemberAttribute

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

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

Aa347692.note(ru-ru,VS.100).gifПримечание
Чтобы задать данное свойство в контрактах сбоев и сообщений, необходимо понимать работу этих функций. Дополнительные сведения см. в разделе в разделах Как устанавливать свойства ProtectionLevel и Использование контрактов сообщений.

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

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

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

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

Ниже приведен контракт службы:

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

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

<ServiceContract()> _
Public Interface IPurchaseOrder
    <OperationContract()> _
    Function Tax() As Integer

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

    [OperationContract(ProtectionLevel = ProtectionLevel.Sign)]
    int Price();
}

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

См. также

Задачи

Как устанавливать свойства ProtectionLevel

Справочник

ServiceContractAttribute
OperationContractAttribute
FaultContractAttribute
MessageContractAttribute
MessageHeaderAttribute
MessageBodyMemberAttribute
ProtectionLevel

Основные понятия

Защита служб
Задание и обработка сбоев в контрактах и службах
Использование контрактов сообщений