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


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

Уровень защиты можно задать, применив соответствующий атрибут и задав свойство. Защиту на уровне службы можно задать таким образом, чтобы она влияла на все части каждого сообщения, либо задать защиту на более детальных уровнях — от методов до частей сообщения. Дополнительные сведения свойстве ProtectionLevel см. в разделе Основные сведения об уровне защиты.

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

Подписание всех сообщений для службы

  1. Создайте интерфейс для службы.

  2. Примените к службе атрибут ServiceContractAttribute и задайте значение Sign для свойства ProtectionLevel, как показано в следующем примере кода (уровень по умолчанию — EncryptAndSign).

    ' Set the ProtectionLevel on the whole service to Sign.
    <ServiceContract(ProtectionLevel:=ProtectionLevel.Sign)> _
    Public Interface ICalculator
    
    // Set the ProtectionLevel on the whole service to Sign.
    [ServiceContract(ProtectionLevel = ProtectionLevel.Sign)]
    public interface ICalculator
    

Подписание всех частей сообщения для операции

  1. Создайте интерфейс для службы и примените к нему атрибут ServiceContractAttribute.

  2. Добавьте в интерфейс объявление метода.

  3. Примените к методу атрибут OperationContractAttribute и задайте значение Sign для свойства ProtectionLevel, как показано в следующем примере кода.

    ' Set the ProtectionLevel on the whole service to Sign.
    <ServiceContract(ProtectionLevel:=ProtectionLevel.Sign)> _
    Public Interface ICalculator
    
        ' Set the ProtectionLevel on this operation to Sign.
        <OperationContract(ProtectionLevel:=ProtectionLevel.Sign)> _
        Function Add(ByVal a As Double, ByVal b As Double) As Double
    End Interface
    
    // Set the ProtectionLevel on the whole service to Sign.
    [ServiceContract(ProtectionLevel = ProtectionLevel.Sign)]
    public interface ICalculator
    {
    
        // Set the ProtectionLevel on this operation to None.
        [OperationContract(ProtectionLevel = ProtectionLevel.Sign)]
        double Add(double a, double b);
    }
    

Защита сообщений об ошибках

Создаваемые в службе исключения можно отправить клиенту в виде ошибок SOAP. Дополнительные сведения создании строго типизированных ошибок см. в разделах Задание и обработка сбоев в контрактах и службах и Практическое руководство. Объявление сбоев в контрактах служб.

Защита сообщения об ошибке

  1. Создайте тип, представляющий сообщение об ошибке. В следующем примере описано создание класса, именуемого MathFault, с двумя полями.

  2. Примените к типу атрибут DataContractAttribute, а к каждому полю, которое должно быть сериализовано, — атрибут DataMemberAttribute, как показано в следующем примере кода.

    <DataContract()>  _
    Public Class MathFault
        <DataMember()>  _
        Public operation As String
        <DataMember()>  _
        Public description As String
    End Class 
    
    [DataContract]
    public class MathFault
    {
        [DataMember]
        public string operation;
        [DataMember]
        public string description;
    }
    
  3. Примените атрибут FaultContractAttribute к методу, который будет возвращать ошибку, и настройте параметр detailType к типу класса ошибки в интерфейсе, который будет возвращать ошибку,

  4. Задайте для свойства ProtectionLevel значение EncryptAndSign в конструкторе, как показано в следующем примере кода.

    Public Interface ICalculator
        ' Set the ProtectionLevel on a FaultContractAttribute.
        <OperationContract(ProtectionLevel := ProtectionLevel.EncryptAndSign), _
         FaultContract(GetType(MathFault), ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
        Function Add(ByVal a As Double, ByVal b As Double) As Double 
    End Interface 
    
    public interface ICalculator
    {
        // Set the ProtectionLevel on a FaultContractAttribute.
        [OperationContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
        [FaultContract(
            typeof(MathFault),
            Action = @"https://localhost/Add",
            Name = "AddFault",
            Namespace = "https://contoso.com",
            ProtectionLevel = ProtectionLevel.EncryptAndSign)]
        double Add(double a, double b);
    }
    

Защита частей сообщения

Для защиты частей сообщения следует использовать контракт сообщения. Дополнительные сведения контрактах сообщения см. в разделе Использование контрактов сообщений

Защита тела сообщения

  1. Создайте тип, представляющий сообщение. В следующем примере описано создание класса Company двумя полями: CompanyName и CompanyID.

  2. Примените атрибут MessageContractAttribute к классу и задайте значение EncryptAndSign для свойства ProtectionLevel.

  3. Примените атрибут MessageHeaderAttribute к полю, которое будет выражено как заголовок сообщения, и задайте значение EncryptAndSign для свойства ProtectionLevel.

  4. Примените атрибут MessageBodyMemberAttribute к любому полю, которое будет выражено как часть текста сообщения, и задайте значение ProtectionLevel для свойства EncryptAndSign, как показано в следующем примере.

    <MessageContract(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
    Public Class Company
        <MessageHeader(ProtectionLevel := ProtectionLevel.Sign)>  _
        Public CompanyName As String
    
        <MessageBodyMember(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
        Public CompanyID As String
    End Class 
    
    [MessageContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    public class Company
    {
        [MessageHeader(ProtectionLevel = ProtectionLevel.Sign)]
        public string CompanyName;
    
        [MessageBodyMember(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
        public string CompanyID;
    }
    

Пример

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

<ServiceContract(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
Public Interface ICalculator
    <OperationContract(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
    Function Add(ByVal a As Double, ByVal b As Double) As Double 
    
    
    <OperationContract(), _
       FaultContract _
       (GetType(MathFault), _
       Action := "https://localhost/Add", _
       Name := "AddFault", _
       Namespace :="https://contoso.com", _
       ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
    Function Subtract(ByVal a As Double, ByVal b As Double) As Double 
    
    <OperationContract(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
    Function GetCompanyInfo() As Company 
End Interface 


<DataContract()>  _
Public Class MathFault
    <DataMember()>  _
    Public operation As String
    <DataMember()>  _
    Public description As String
End Class 

<MessageContract(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
Public Class Company
    <MessageHeader(ProtectionLevel := ProtectionLevel.Sign)>  _
    Public CompanyName As String
    
    <MessageBodyMember(ProtectionLevel := ProtectionLevel.EncryptAndSign)>  _
    Public CompanyID As String
End Class 

<MessageContract(ProtectionLevel := ProtectionLevel.Sign)>  _
Public Class Calculator
    Implements ICalculator
    
    Public Function Add(ByVal a As Double, ByVal b As Double) As Double _
      Implements ICalculator.Add
        Return a + b
    
    End Function 
    
    Public Function Subtract(ByVal a As Double, ByVal b As Double) As Double _
       Implements ICalculator.Subtract
        Return a - b
    
    End Function      
    
    Public Function GetCompanyInfo() As Company Implements ICalculator.GetCompanyInfo
        Dim co As New Company()
        co.CompanyName = "www.cohowinery.com"
        Return co
    End Function 
End Class 


Public Class Test
    
    Shared Sub Main() 
        Dim t As New Test()
        Try
            t.Run()
        Catch inv As System.InvalidOperationException
            Console.WriteLine(inv.Message)
        End Try
    End Sub 
    
    
    Private Sub Run() 
        ' Create a binding and set the security mode to Message.
        Dim b As New WSHttpBinding()
        b.Security.Mode = SecurityMode.Message
        
        Dim contractType As Type = GetType(ICalculator)
        Dim implementedContract As Type = GetType(Calculator)
        Dim baseAddress As New Uri("https://localhost:8044/base")
        
        ' Create the ServiceHost and add an endpoint.
        Dim sh As New ServiceHost(implementedContract, baseAddress)
        sh.AddServiceEndpoint(contractType, b, "Calculator")
        
        Dim sm As New ServiceMetadataBehavior()
        sm.HttpGetEnabled = True
        sh.Description.Behaviors.Add(sm)
        sh.Credentials.ServiceCertificate.SetCertificate( _
           StoreLocation.CurrentUser, StoreName.My, _
           X509FindType.FindByIssuerName, "ValidCertificateIssuer")
        
        Dim se As ServiceEndpoint
        For Each se In  sh.Description.Endpoints
            Dim cd As ContractDescription = se.Contract
            Console.WriteLine(vbLf + "ContractDescription: ProtectionLevel = {0}", _
               cd.Name, cd.ProtectionLevel)
            Dim od As OperationDescription
            For Each od In  cd.Operations
                Console.WriteLine(vbLf + "OperationDescription: Name = {0}", od.Name, od.ProtectionLevel)
                Console.WriteLine("ProtectionLevel = {1}", od.Name, od.ProtectionLevel)
                Dim m As MessageDescription
                For Each m In  od.Messages
                    Console.WriteLine(vbTab + " {0}: {1}", m.Action, m.ProtectionLevel)
                    Dim mh As MessageHeaderDescription
                    For Each mh In  m.Headers
                        Console.WriteLine(vbTab + vbTab + " {0}: {1}", mh.Name, mh.ProtectionLevel)
                        
                        Dim mp As MessagePropertyDescription
                        For Each mp In  m.Properties
                            Console.WriteLine("{0}: {1}", mp.Name, mp.ProtectionLevel)
                        Next mp
                    Next mh
                Next m
            Next od
        Next se
        sh.Open()
        Console.WriteLine("Listening")
        Console.ReadLine()
        sh.Close()
    
    End Sub 
End Class 
[ServiceContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
public interface ICalculator
{
    [OperationContract(ProtectionLevel = ProtectionLevel.Sign)]
    double Add(double a, double b);


    [OperationContract()]
    [FaultContract(typeof(MathFault),
        ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    double Subtract(double a, double b);

    [OperationContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    Company GetCompanyInfo();
}


[DataContract]
public class MathFault
{
    [DataMember]
    public string operation;
    [DataMember]
    public string description;
}

[MessageContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
public class Company
{
    [MessageHeader(ProtectionLevel = ProtectionLevel.Sign)]
    public string CompanyName;

    [MessageBodyMember(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    public string CompanyID;
}

[MessageContract(ProtectionLevel = ProtectionLevel.Sign)]
public class Calculator : ICalculator
{
    public double Add(double a, double b)
    {
        return a + b;
    }


    public double Subtract(double a, double b)
    {
        return a - b;
    }

    public Company GetCompanyInfo()
    {
        Company co = new Company();
        co.CompanyName = "www.cohowinery.com";
        return co;
    }

}

public class Test
{
    static void Main()
    {
        Test t = new Test();
        try
        {
            t.Run();
        }
        catch (System.InvalidOperationException inv)
        {
            Console.WriteLine(inv.Message);
        }
    }

    private void Run()
    {
        // Create a binding and set the security mode to Message.
        WSHttpBinding b = new WSHttpBinding();
        b.Security.Mode = SecurityMode.Message;

        Type contractType = typeof(ICalculator);
        Type implementedContract = typeof(Calculator);
        Uri baseAddress = new Uri("https://localhost:8044/base");

        // Create the ServiceHost and add an endpoint.
        ServiceHost sh = new ServiceHost(implementedContract, baseAddress);
        sh.AddServiceEndpoint(contractType, b, "Calculator");

        ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
        sm.HttpGetEnabled = true;
        sh.Description.Behaviors.Add(sm);
        sh.Credentials.ServiceCertificate.SetCertificate(
            StoreLocation.CurrentUser,
            StoreName.My,
            X509FindType.FindByIssuerName,
            "ValidCertificateIssuer");

        foreach (ServiceEndpoint se in sh.Description.Endpoints)
        {
            ContractDescription cd = se.Contract;
            Console.WriteLine("\nContractDescription: ProtectionLevel = {0}", cd.Name, cd.ProtectionLevel);
            foreach (OperationDescription od in cd.Operations)
            {
                Console.WriteLine("\nOperationDescription: Name = {0}", od.Name, od.ProtectionLevel);
                Console.WriteLine("ProtectionLevel = {1}", od.Name, od.ProtectionLevel);
                foreach (MessageDescription m in od.Messages)
                {
                    Console.WriteLine("\t {0}: {1}", m.Action, m.ProtectionLevel);
                    foreach (MessageHeaderDescription mh in m.Headers)
                    {
                        Console.WriteLine("\t\t {0}: {1}", mh.Name, mh.ProtectionLevel);

                        foreach (MessagePropertyDescription mp in m.Properties)
                        {
                            Console.WriteLine("{0}: {1}", mp.Name, mp.ProtectionLevel);
                        }
                    }
                }
            }
        }
        sh.Open();
        Console.WriteLine("Listening");
        Console.ReadLine();
        sh.Close();

    }
}

Компиляция кода

В следующем примере кода показаны пространства имен, необходимые для компиляции примера кода.

Imports System
Imports System.ServiceModel
Imports System.Net.Security
Imports System.ServiceModel.Description
Imports System.Security.Permissions
Imports System.Security.Cryptography.X509Certificates
Imports System.Runtime.Serialization
using System;
using System.ServiceModel;
using System.Net.Security;
using System.ServiceModel.Description;
using System.Security.Permissions;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.Serialization;

См. также

Справочник

ServiceContractAttribute
OperationContractAttribute
FaultContractAttribute
MessageContractAttribute
MessageBodyMemberAttribute

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

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