如何:设置 ProtectionLevel 属性
通过应用相应的属性 (Attribute) 并设置该属性 (Property) 可设置保护级别。可在服务级设置保护以影响每条消息的所有部件,或者从方法到消息部分逐级递增地设置保护。有关 ProtectionLevel 属性的更多信息,请参见了解保护级别。
注意: |
---|
只能在代码中,而不是在配置中设置保护级别。 |
为服务签名所有消息
为服务创建一个接口。
将 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
为操作签名所有消息部分
为服务创建一个接口,并将 ServiceContractAttribute 属性应用于该接口。
向该接口添加一个方法声明。
将 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 错误发送到客户端。有关创建强类型错误的更多信息,请参见在协定和服务中指定和处理错误和如何:在服务协定中声明错误。
保护错误消息
创建一个表示错误消息的类型。下面的示例创建一个含有两个字段的名为
MathFault
的类。将 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; }
在将返回该错误的接口中,将 FaultContractAttribute 属性应用于将返回错误的方法,并将 detailType 参数设置为错误类的类型。
同样在构造函数中,将 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); }
保护消息部分
使用消息协定保护消息的各个部分。有关消息协定的更多信息,请参见使用消息约定。
保护消息正文
创建一个表示消息的类型。下面的示例创建一个
Company
类,其中有两个字段CompanyName
和CompanyID
。将 MessageContractAttribute 属性 (Attribute) 应用于该类,并将 ProtectionLevel 属性 (Property) 设置为 EncryptAndSign。
将 MessageHeaderAttribute 属性 (Attribute) 应用于将表示为消息头的字段,并将
ProtectionLevel
属性 (Property) 设置为 EncryptAndSign。将 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