Procedura: impostare la proprietà ProtectionLevel
È possibile impostare il livello di protezione applicando un attributo appropriato e impostando la proprietà. È possibile impostare la protezione a livello di servizio su tutte le parti di ogni messaggio. In alternativa è possibile impostare la protezione a livelli granulari in modo crescente, dai metodi alle parti del messaggio. Per ulteriori informazioni su sulla proprietà ProtectionLevel, vedere Informazioni sul livello di protezione.
Nota: |
---|
È possibile impostare i livelli di protezione solo nel codice, non nella configurazione. |
Per firmare tutti i messaggi per un servizio
Creare un'interfaccia per il servizio.
Applicare l'attributo ServiceContractAttribute al servizio e impostare la proprietà ProtectionLevel su Sign, come illustrato nel codice seguente (il livello predefinito è 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
Per firmare tutte le parti del messaggio per un'operazione
Creare un'interfaccia per il servizio e applicarvi l'attributo ServiceContractAttribute.
Aggiungere una dichiarazione di metodo all'interfaccia.
Applicare l'attributo OperationContractAttribute al metodo e impostare la proprietà ProtectionLevel su Sign, come illustrato nel codice seguente.
' 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); }
Protezione dei messaggi di errore
È possibile inviare le eccezioni generate in un servizio a un client come errori SOAP. Per ulteriori informazioni su sulla creazione di errori fortemente tipizzati, vedere Specifica e gestione di errori in contratti e servizi e Procedura: dichiarare errori nei contratti di servizio.
Per proteggere i messaggi di errore
Creare un tipo che rappresenta il messaggio di errore. Nell'esempio seguente viene creata una classe denominata
MathFault
con due campi.Applicare l'attributo DataContractAttribute al tipo e un attributo DataMemberAttribute a ogni campo che deve essere serializzato, come illustrato nel codice seguente.
<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; }
Nell'interfaccia che restituirà l'errore, applicare l'attributo FaultContractAttribute al metodo che restituirà l'errore e impostare il parametro detailType sul tipo della classe di errore.
Nel costruttore, inoltre, impostare la proprietà ProtectionLevel su EncryptAndSign, come illustrato nel codice seguente.
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); }
Protezione delle parti del messaggio
Utilizzare un contratto di messaggio per proteggere le parti di un messaggio. Per ulteriori informazioni su sui contratti di messaggio, vedere Utilizzo dei contratti di messaggio.
Per proteggere il corpo del messaggio
Creare un tipo che rappresenta il messaggio. Nell'esempio seguente viene creata una classe
Company
con due campi,CompanyName
eCompanyID
.Applicare l'attributo MessageContractAttribute alla classe e impostare la proprietà ProtectionLevel su EncryptAndSign.
Applicare l'attributo MessageHeaderAttribute a un campo che verrà espresso come intestazione del messaggio e impostare la proprietà
ProtectionLevel
su EncryptAndSign.Applicare l'elemento MessageBodyMemberAttribute a qualsiasi campo che sarà espresso come parte del corpo del messaggio e impostare la proprietà
ProtectionLevel
su EncryptAndSign, come illustrato nell'esempio seguente.<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; }
Esempio
Nell'esempio seguente viene impostata la proprietà ProtectionLevel
di diverse classi Attribute in varie posizioni di un servizio.
<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();
}
}
Compilazione del codice
Nel codice seguente vengono illustrati gli spazi dei nomi necessari per compilare il codice di esempio.
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;
Vedere anche
Riferimento
ServiceContractAttribute
OperationContractAttribute
FaultContractAttribute
MessageContractAttribute
MessageBodyMemberAttribute