方法: ProtectionLevel プロパティを設定する

適切な属性を適用してプロパティを設定することで、保護レベルを設定できます。 サービス レベルですべてのメッセージのすべての部分に影響する保護を設定したり、メソッドからメッセージ部分まで、段階的にきめ細かなレベルで保護を設定したりすることができます。 ProtectionLevel プロパティの詳細については、「保護レベルの理解」を参照してください。

Note

保護レベルは構成ではなく、コードでのみ設定できます。

サービスのすべてのメッセージに署名するには

  1. サービス用のインターフェイスを作成します。

  2. 次のコードに示すように、ServiceContractAttribute 属性をサービスに適用し、ProtectionLevel プロパティを 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 属性を適用し、ProtectionLevel プロパティを Sign に設定します。

    // 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
    

エラー メッセージの保護

サービスでスローされた例外は、SOAP エラーとしてクライアントに送信できます。 厳密に型指定されたエラーの作成方法の詳細については、「コントラクトおよびサービスのエラーの指定と処理」と「方法: サービス コントラクトでのエラーを宣言する」を参照してください。

エラー メッセージを保護するには

  1. エラー メッセージを表す型を作成します。 次の例では、2 つのフィールドを持つ MathFault という名前のクラスを作成します。

  2. 次のコードに示すように、型に DataContractAttribute 属性を適用し、シリアル化する必要のある各フィールドに DataMemberAttribute 属性を適用します。

    [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
    
  3. エラーを返すインターフェイスで、エラーを返すメソッドに FaultContractAttribute 属性を適用し、エラー クラスの型に detailType パラメーターを設定します。

  4. 次のコードに示すように、コンストラクターでも、ProtectionLevel プロパティを EncryptAndSign に設定します。

    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
    

メッセージ部分の保護

メッセージ部分を保護するには、メッセージ コントラクトを使用します。 メッセージ コントラクトの詳細については、「メッセージ コントラクトの使用」を参照してください。

メッセージ本文を保護するには

  1. メッセージを表す型を作成します。 次の例では、CompanyCompanyName の 2 つのフィールドを持つ CompanyID クラスを作成します。

  2. このクラスに MessageContractAttribute 属性を適用し、ProtectionLevel プロパティを EncryptAndSign に設定します。

  3. メッセージ ヘッダーとして表現されるフィールドに MessageHeaderAttribute 属性を適用し、ProtectionLevel プロパティを EncryptAndSign に設定します。

  4. 次の例に示すように、メッセージ本文の一部として表現される任意のフィールドに MessageBodyMemberAttribute を適用し、ProtectionLevel プロパティを EncryptAndSign に設定します。

    [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
    

次の例では、サービスのいろいろな場所で、いくつかの属性クラスの ProtectionLevel プロパティを設定します。

[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

コードのコンパイル

コード例のコンパイルに必要な名前空間を、次のコードに示します。

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

関連項目