如何:设置 ProtectionLevel 属性

通过应用相应的属性 (Attribute) 并设置该属性 (Property) 可设置保护级别。可在服务级设置保护以影响每条消息的所有部件,或者从方法到消息部分逐级递增地设置保护。有关 ProtectionLevel 属性的更多信息,请参见了解保护级别

Aa347791.note(zh-cn,VS.100).gif注意:
只能在代码中,而不是在配置中设置保护级别。

为服务签名所有消息

  1. 为服务创建一个接口。

  2. ServiceContractAttribute 属性 (Attribute) 应用于服务,并将 ProtectionLevel 属性 (Property) 设置为 Sign,如下面的代码所示(默认级别为 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 属性 (Attribute) 应用于该方法,并将 ProtectionLevel 属性 (Property) 设置为 Sign,如下面的代码所示。

    ' 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 类,其中有两个字段 CompanyNameCompanyID

  2. MessageContractAttribute 属性 (Attribute) 应用于该类,并将 ProtectionLevel 属性 (Property) 设置为 EncryptAndSign

  3. MessageHeaderAttribute 属性 (Attribute) 应用于将表示为消息头的字段,并将 ProtectionLevel 属性 (Property) 设置为 EncryptAndSign

  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;
    }
    

示例

下面的示例设置位于服务中不同位置的多个属性 (Attribute) 类的 ProtectionLevel 属性 (Property)。

<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

概念

了解保护级别