Partager via


Comment : définir la propriété ProtectionLevel

Vous pouvez définir le niveau de protection en appliquant un attribut approprié et en définissant la propriété. Vous pouvez définir la protection au niveau du service afin d'affecter toutes les parties de chaque message, ou vous pouvez la définir à des niveaux de plus en plus spécifiques, des méthodes aux parties du message. Pour plus d'informations sur le sujet suivant la propriété ProtectionLevel, consultez Fonctionnement des niveaux de protection.

Aa347791.note(fr-fr,VS.100).gifRemarque :
Vous pouvez définir des niveaux de protection dans le code uniquement, mais pas dans la configuration.

Pour signer tous les messages d'un service

  1. Créez une interface pour le service.

  2. Appliquez l'attribut ServiceContractAttribute au service et affectez Sign à la propriété ProtectionLevel, tel qu'indiqué dans le code suivant (le niveau par défaut est 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
    

Pour signer toutes les parties de message d'une opération

  1. Créez une interface pour le service et appliquez l'attribut ServiceContractAttribute à celle-ci.

  2. Ajoutez une déclaration de méthode à l'interface.

  3. Appliquez l'attribut OperationContractAttribute à la méthode et affectez Sign à la propriété ProtectionLevel, tel qu'indiqué dans le code suivant.

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

Protection des messages d'erreur

Les exceptions levées sur un service peuvent être envoyées à un client en tant qu'erreurs SOAP. Pour plus d'informations sur le sujet suivant la création d'erreurs fortement typées, consultez Spécification et gestion des erreurs dans les contrats et les services et Comment : déclarer des erreurs dans des contrats de service.

Pour protéger un message d'erreur

  1. Créez un type qui représente le message d'erreur. L'exemple suivant crée une classe appelée MathFault contenant deux champs.

  2. Appliquez l'attribut DataContractAttribute au type et un attribut DataMemberAttribute à chaque champ qui doit être sérialisé, tel qu'indiqué dans le code suivant.

    <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. Dans l'interface qui retournera l'erreur, appliquez l'attribut FaultContractAttribute à la méthode que retournera l'erreur et affectez le type de la classe d'erreur au paramètre detailType.

  4. Également dans le constructeur, affectez EncryptAndSign à la propriété ProtectionLevel, tel qu'indiqué dans le code suivant.

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

Protection de parties de message

Utilisez un contrat de message pour protéger les parties d'un message. Pour plus d'informations sur le sujet suivant les contrats de messages, consultez Utilisation de contrats de message.

Pour protéger le corps d'un message

  1. Créez un type qui représente le message. L'exemple suivant crée une classe Company contenant deux champs, CompanyName et CompanyID.

  2. Appliquez l'attribut MessageContractAttribute à la classe et affectez EncryptAndSign à la propriété ProtectionLevel.

  3. Appliquez l'attribut MessageHeaderAttribute à un champ qui sera exprimé sous forme d'un en-tête de message et affectez EncryptAndSign à la propriété ProtectionLevel.

  4. Appliquez l'objet MessageBodyMemberAttribute aux champs qui seront exprimés sous la forme du corps du message et affectez EncryptAndSign à la propriété ProtectionLevel , tel qu'indiqué dans l'exemple suivant.

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

Exemple

L'exemple suivant définit la propriété ProtectionLevel de plusieurs classes d'attributs à divers emplacements dans un service.

<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();

    }
}

Compilation du code

Le code suivant présente les espaces de noms requis pour compiler l'exemple de code.

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;

Voir aussi

Référence

ServiceContractAttribute
OperationContractAttribute
FaultContractAttribute
MessageContractAttribute
MessageBodyMemberAttribute

Concepts

Fonctionnement des niveaux de protection