Instrukcje: Ustawianie właściwości ProtectionLevel
Poziom ochrony można ustawić, stosując odpowiedni atrybut i ustawiając właściwość. Ochronę na poziomie usługi można ustawić tak, aby wpływała na wszystkie części każdego komunikatu lub ustawić ochronę na coraz bardziej szczegółowych poziomach— od metod do części komunikatów. Aby uzyskać więcej informacji na temat ProtectionLevel
właściwości, zobacz Understanding Protection Level (Opis poziomu ochrony).
Uwaga
Poziomy ochrony można ustawić tylko w kodzie, a nie w konfiguracji.
Aby podpisać wszystkie komunikaty dla usługi
Utwórz interfejs dla usługi.
ServiceContractAttribute Zastosuj atrybut do usługi i ustaw ProtectionLevel właściwość na Sign, jak pokazano w poniższym kodzie (domyślnym poziomem jest 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
Aby podpisać wszystkie części komunikatów dla operacji
Utwórz interfejs dla usługi i zastosuj ServiceContractAttribute atrybut do interfejsu.
Dodaj deklarację metody do interfejsu.
OperationContractAttribute Zastosuj atrybut do metody i ustaw ProtectionLevel właściwość na Sign, jak pokazano w poniższym kodzie.
// 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); }
' 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
Ochrona komunikatów o błędach
Wyjątki zgłaszane w usłudze mogą być wysyłane do klienta jako błędy protokołu SOAP. Aby uzyskać więcej informacji na temat tworzenia silnie typiowanych błędów, zobacz Określanie i obsługa błędów w kontraktach i usługach oraz Instrukcje: deklarowanie błędów w kontraktach usług.
Aby chronić komunikat o błędzie
Utwórz typ reprezentujący komunikat o błędzie. Poniższy przykład tworzy klasę o nazwie
MathFault
z dwoma polami.DataContractAttribute Zastosuj atrybut do typu i DataMemberAttribute atrybutu do każdego pola, które powinno być serializowane, jak pokazano w poniższym kodzie.
[DataContract] public class MathFault { [DataMember] public string operation; [DataMember] public string description; }
<DataContract()> _ Public Class MathFault <DataMember()> _ Public operation As String <DataMember()> _ Public description As String End Class
W interfejsie, który zwróci błąd, zastosuj FaultContractAttribute atrybut do metody, która zwróci błąd i ustawi
detailType
parametr na typ klasy błędów.Również w konstruktorze ustaw ProtectionLevel właściwość na EncryptAndSign, jak pokazano w poniższym kodzie.
public interface ICalculator { // Set the ProtectionLevel on a FaultContractAttribute. [OperationContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)] [FaultContract( typeof(MathFault), Action = @"http://localhost/Add", Name = "AddFault", Namespace = "http://contoso.com", ProtectionLevel = ProtectionLevel.EncryptAndSign)] double Add(double a, double b); }
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
Ochrona części komunikatów
Użyj kontraktu komunikatów, aby chronić części komunikatu. Aby uzyskać więcej informacji na temat kontraktów komunikatów, zobacz Using Message Contracts (Używanie kontraktów komunikatów).
Aby chronić treść wiadomości
Utwórz typ reprezentujący komunikat. Poniższy przykład tworzy klasę
Company
z dwoma polamiCompanyName
iCompanyID
.MessageContractAttribute Zastosuj atrybut do klasy i ustaw ProtectionLevel właściwość na EncryptAndSign.
MessageHeaderAttribute Zastosuj atrybut do pola, które będzie wyrażone jako nagłówek komunikatu
ProtectionLevel
i ustaw właściwość na EncryptAndSign.Zastosuj element MessageBodyMemberAttribute do dowolnego pola, które zostanie wyrażone jako część treści komunikatu, i ustaw
ProtectionLevel
właściwość na EncryptAndSignwartość , jak pokazano w poniższym przykładzie.[MessageContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)] public class Company { [MessageHeader(ProtectionLevel = ProtectionLevel.Sign)] public string CompanyName; [MessageBodyMember(ProtectionLevel = ProtectionLevel.EncryptAndSign)] public string CompanyID; }
<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
Przykład
Poniższy przykład ustawia ProtectionLevel
właściwość kilku klas atrybutów w różnych miejscach w usłudze.
[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("http://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();
}
}
<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:="http://localhost/Add", _
Name:="AddFault", _
Namespace:="http://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("http://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
Kompilowanie kodu
Poniższy kod przedstawia przestrzenie nazw wymagane do skompilowania przykładowego kodu.
using System;
using System.ServiceModel;
using System.Net.Security;
using System.ServiceModel.Description;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.Serialization;
Imports System.ServiceModel
Imports System.Net.Security
Imports System.ServiceModel.Description
Imports System.Security.Cryptography.X509Certificates
Imports System.Runtime.Serialization