Sdílet prostřednictvím


Postupy: Konfigurace klienta WCF na vzájemnou spolupráci se službami WSE3.0

Klienti wcf (Windows Communication Foundation) jsou kompatibilní s vylepšeními webových služeb 3.0 pro služby Microsoft .NET (WSE), pokud jsou klienti WCF nakonfigurováni tak, aby používali verzi specifikace WS-Adresování ze srpna 2004.

Konfigurace klienta WCF pro spolupráci s webovou službou WSE 3.0

  1. Spuštěním nástroje ServiceModel Metadata Utility (Svcutil.exe) vytvořte klienta WCF pro webovou službu WSE 3.0.

    Pro webovou službu WSE se vytvoří klientská třída WCF.

    Podrobnosti o vytvoření klienta WCF najdete v tématu Postupy: Vytvoření klienta.

  2. Vytvořte třídu, která představuje vazbu, která může komunikovat s webovými službami WSE 3.0.

    Následující třída je součástí spolupráce s ukázkou WSE .

    1. Vytvořte třídu, která je odvozena od třídy Binding.

      Následující příklad kódu vytvoří třídu s názvem WseHttpBinding , která je odvozena z Binding třídy.

      public class WseHttpBinding : Binding
      {
      
      Public Class WseHttpBinding
          Inherits Binding
      
    2. Přidejte vlastnosti do třídy, která určuje kontrolní výraz klíče WSE, zda jsou požadovány odvozené klíče, zda jsou použity zabezpečené relace, zda jsou vyžadovány potvrzení podpisu a nastavení ochrany zpráv.

      Následující příklad kódu definuje SecurityAssertion, , RequireDerivedKeysEstablishSecurityContexta MessageProtectionOrder vlastnosti. Určují kontrolní výraz WSE na klíč, zda jsou odvozené klíče požadovány, zda jsou použity zabezpečené relace, zda jsou vyžadovány potvrzení podpisu a nastavení ochrany zpráv.

      
      private WseSecurityAssertion assertion;
      public WseSecurityAssertion SecurityAssertion
      {
          get { return assertion; }
          set { assertion = value; }
      }
      
      private bool requireDerivedKeys;
      public bool RequireDerivedKeys
      {
          get { return requireDerivedKeys; }
          set { requireDerivedKeys = value; }
      }
      
      private bool establishSecurityContext;
      public bool EstablishSecurityContext
      {
          get { return establishSecurityContext; }
          set { establishSecurityContext = value; }
      }
      
      private bool requireSignatureConfirmation;
      public bool RequireSignatureConfirmation
      {
          get { return requireSignatureConfirmation; }
          set { requireSignatureConfirmation = value; }
      }
      
      private MessageProtectionOrder messageProtectionOrder;
      public MessageProtectionOrder MessageProtectionOrder
      {
          get { return messageProtectionOrder; }
          set { messageProtectionOrder = value; }
      }
      
      Public Property SecurityAssertion() As WseSecurityAssertion
      
          Get
      
              Return assertion
      
          End Get
          Set(ByVal value As WseSecurityAssertion)
      
              assertion = value
      
          End Set
      
      End Property
      
      Private m_requireDerivedKeys As Boolean
      Public Property RequireDerivedKeys() As Boolean
      
          Get
      
              Return m_requireDerivedKeys
      
          End Get
          Set(ByVal value As Boolean)
      
              m_requireDerivedKeys = value
      
          End Set
      
      End Property
      
      Private m_establishSecurityContext As Boolean
      Public Property EstablishSecurityContext() As Boolean
      
          Get
      
              Return m_establishSecurityContext
      
          End Get
          Set(ByVal value As Boolean)
      
              m_establishSecurityContext = value
      
          End Set
      
      End Property
      
      Private m_requireSignatureConfirmation As Boolean
      Public Property RequireSignatureConfirmation() As Boolean
      
          Get
      
              Return m_requireSignatureConfirmation
      
          End Get
          Set(ByVal value As Boolean)
      
              m_requireSignatureConfirmation = value
      
          End Set
      
      End Property
      
      Private m_messageProtectionOrder As MessageProtectionOrder
      Public Property MessageProtectionOrder() As MessageProtectionOrder
      
          Get
      
              Return m_messageProtectionOrder
      
          End Get
          Set(ByVal value As MessageProtectionOrder)
      
              m_messageProtectionOrder = value
      
          End Set
      
      End Property
      
    3. Přepište metodu CreateBindingElements pro nastavení vlastností vazby.

      Následující příklad kódu určuje přenos, kódování zpráv a nastavení ochrany zpráv získáním hodnot SecurityAssertion a MessageProtectionOrder vlastností.

      public override BindingElementCollection CreateBindingElements()
      {
          //SecurityBindingElement sbe = bec.Find<SecurityBindingElement>();
          BindingElementCollection bec = new BindingElementCollection();
          // By default http transport is used
          SecurityBindingElement securityBinding;
          BindingElement transport;
      
          switch (assertion)
          {
              case WseSecurityAssertion.UsernameOverTransport:
                  transport = new HttpsTransportBindingElement();
                  securityBinding = (TransportSecurityBindingElement)SecurityBindingElement.CreateUserNameOverTransportBindingElement();
                  if (establishSecurityContext == true)
                      throw new InvalidOperationException("Secure Conversation is not supported for this Security Assertion Type");
                  if (requireSignatureConfirmation == true)
                      throw new InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type");
                  break;
              case WseSecurityAssertion.MutualCertificate10:
                  transport = new HttpTransportBindingElement();
                  securityBinding = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
                  if (requireSignatureConfirmation == true)
                      throw new InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type");
                  ((AsymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;
                  break;
              case WseSecurityAssertion.UsernameForCertificate:
                  transport = new HttpTransportBindingElement();
                  securityBinding = (SymmetricSecurityBindingElement)SecurityBindingElement.CreateUserNameForCertificateBindingElement();
                  // We want signatureconfirmation on the bootstrap process
                  // either for the application messages or for the RST/RSTR
                  ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;
                  ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;
                  break;
              case WseSecurityAssertion.AnonymousForCertificate:
                  transport = new HttpTransportBindingElement();
                  securityBinding = (SymmetricSecurityBindingElement)SecurityBindingElement.CreateAnonymousForCertificateBindingElement();
                  ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;
                  ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;
                  break;
              case WseSecurityAssertion.MutualCertificate11:
                  transport = new HttpTransportBindingElement();
                  securityBinding = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11);
                  ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;
                  ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;
                  break;
              case WseSecurityAssertion.Kerberos:
                  transport = new HttpTransportBindingElement();
                  securityBinding = (SymmetricSecurityBindingElement)SecurityBindingElement.CreateKerberosBindingElement();
                  ((SymmetricSecurityBindingElement)securityBinding).RequireSignatureConfirmation = requireSignatureConfirmation;
                  ((SymmetricSecurityBindingElement)securityBinding).MessageProtectionOrder = messageProtectionOrder;
                  break;
              default:
                  throw new NotSupportedException("This supplied Wse security assertion is not supported");
          }
          //Set defaults for the security binding
          securityBinding.IncludeTimestamp = true;
      
          // Derived Keys
          // set the preference for derived keys before creating SecureConversationBindingElement
          securityBinding.SetKeyDerivation(requireDerivedKeys);
      
          //Secure Conversation
          if (establishSecurityContext == true)
          {
              SymmetricSecurityBindingElement secureconversation =
                      (SymmetricSecurityBindingElement)SymmetricSecurityBindingElement.CreateSecureConversationBindingElement(
                                                  securityBinding, false);
              // This is the default
              //secureconversation.DefaultProtectionLevel = ProtectionLevel.EncryptAndSign;
      
              //Set defaults for the secure conversation binding
              secureconversation.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
              // We do not want signature confirmation on the application level messages
              // when secure conversation is enabled.
              secureconversation.RequireSignatureConfirmation = false;
              secureconversation.MessageProtectionOrder = messageProtectionOrder;
              secureconversation.SetKeyDerivation(requireDerivedKeys);
              securityBinding = secureconversation;
          }
      
          // Add the security binding to the binding collection
          bec.Add(securityBinding);
      
          // Add the message encoder.
          TextMessageEncodingBindingElement textelement = new TextMessageEncodingBindingElement();
          textelement.MessageVersion = MessageVersion.Soap11WSAddressingAugust2004;
          //These are the defaults required for WSE
          //textelement.MessageVersion = MessageVersion.Soap11Addressing1;
          //textelement.WriteEncoding = System.Text.Encoding.UTF8;
          bec.Add(textelement);
      
          // Add the transport
          bec.Add(transport);
      
          // return the binding elements
          return bec;
      }
      
      Public Overloads Overrides Function CreateBindingElements() As BindingElementCollection
      
          'SecurityBindingElement sbe = bec.Find<SecurityBindingElement>();
          Dim bec As New BindingElementCollection()
          ' By default http transport is used
          Dim securityBinding As SecurityBindingElement
          Dim transport As BindingElement
      
          Select Case assertion
      
              Case WseSecurityAssertion.UsernameOverTransport
                  transport = New HttpsTransportBindingElement()
                  securityBinding = DirectCast(SecurityBindingElement.CreateUserNameOverTransportBindingElement(), TransportSecurityBindingElement)
                  If m_establishSecurityContext = True Then
                      Throw New InvalidOperationException("Secure Conversation is not supported for this Security Assertion Type")
                  End If
                  If m_requireSignatureConfirmation = True Then
                      Throw New InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type")
                  End If
                  Exit Select
              Case WseSecurityAssertion.MutualCertificate10
                  transport = New HttpTransportBindingElement()
                  securityBinding = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10)
                  If m_requireSignatureConfirmation = True Then
                      Throw New InvalidOperationException("Signature Confirmation is not supported for this Security Assertion Type")
                  End If
                  DirectCast(securityBinding, AsymmetricSecurityBindingElement).MessageProtectionOrder = m_messageProtectionOrder
                  Exit Select
              Case WseSecurityAssertion.UsernameForCertificate
                  transport = New HttpTransportBindingElement()
                  securityBinding = DirectCast(SecurityBindingElement.CreateUserNameForCertificateBindingElement(), SymmetricSecurityBindingElement)
                  ' We want signatureconfirmation on the bootstrap process
                  ' either for the application messages or for the RST/RSTR
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).RequireSignatureConfirmation = m_requireSignatureConfirmation
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).MessageProtectionOrder = m_messageProtectionOrder
                  Exit Select
              Case WseSecurityAssertion.AnonymousForCertificate
                  transport = New HttpTransportBindingElement()
                  securityBinding = DirectCast(SecurityBindingElement.CreateAnonymousForCertificateBindingElement(), SymmetricSecurityBindingElement)
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).RequireSignatureConfirmation = m_requireSignatureConfirmation
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).MessageProtectionOrder = m_messageProtectionOrder
                  Exit Select
              Case WseSecurityAssertion.MutualCertificate11
                  transport = New HttpTransportBindingElement()
                  securityBinding = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11)
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).RequireSignatureConfirmation = m_requireSignatureConfirmation
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).MessageProtectionOrder = m_messageProtectionOrder
                  Exit Select
              Case WseSecurityAssertion.Kerberos
                  transport = New HttpTransportBindingElement()
                  securityBinding = DirectCast(SecurityBindingElement.CreateKerberosBindingElement(), SymmetricSecurityBindingElement)
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).RequireSignatureConfirmation = m_requireSignatureConfirmation
                  DirectCast(securityBinding, SymmetricSecurityBindingElement).MessageProtectionOrder = m_messageProtectionOrder
                  Exit Select
              Case Else
                  Throw New NotSupportedException("This supplied Wse security assertion is not supported")
      
          End Select
      
          'Set defaults for the security binding
          securityBinding.IncludeTimestamp = True
      
          ' Derived Keys
          ' Set the preference for derived keys before creating the binding for SecureConversation.
          securityBinding.SetKeyDerivation(m_requireDerivedKeys)
      
          'Secure Conversation
          If m_establishSecurityContext = True Then
      
              Dim secureconversation As SymmetricSecurityBindingElement = DirectCast(SymmetricSecurityBindingElement.CreateSecureConversationBindingElement(securityBinding, False), SymmetricSecurityBindingElement)
              ' This is the default
              'secureconversation.DefaultProtectionLevel = ProtectionLevel.EncryptAndSign;
      
              'Set defaults for the secure conversation binding
              secureconversation.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256
              ' We do not want signature confirmation on the application level messages
              ' when secure conversation is enabled.
              secureconversation.RequireSignatureConfirmation = False
              secureconversation.MessageProtectionOrder = m_messageProtectionOrder
              secureconversation.SetKeyDerivation(m_requireDerivedKeys)
              securityBinding = secureconversation
      
          End If
      
          ' Add the security binding to the binding collection
          bec.Add(securityBinding)
      
          ' Add the message encoder.
          Dim textelement As New TextMessageEncodingBindingElement()
          textelement.MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap11WSAddressingAugust2004
          'These are the defaults required for WSE
          'textelement.MessageVersion = MessageVersion.Soap11Addressing1;
          'textelement.WriteEncoding = System.Text.Encoding.UTF8;
          bec.Add(textelement)
      
          ' Add the transport
          bec.Add(transport)
      
          ' return the binding elements
          Return bec
      
      End Function
      
  3. V kódu klientské aplikace přidejte kód pro nastavení vlastností vazby.

    Následující příklad kódu určuje, že klient WCF musí používat ochranu zpráv a ověřování definované kontrolním výrazem zabezpečení WSE 3.0 AnonymousForCertificate na klíč. Navíc jsou vyžadovány zabezpečené relace a odvozené klíče.

    static void CallWseService(bool usePolicyFile)
    {
        EndpointAddress address = new EndpointAddress(new Uri("http://localhost/WSSecurityAnonymousPolicy/WSSecurityAnonymousService.asmx"),
                                                      EndpointIdentity.CreateDnsIdentity("WSE2QuickStartServer"));
    
        WseHttpBinding binding = new WseHttpBinding();
        if (!usePolicyFile)
        {
            binding.SecurityAssertion = WseSecurityAssertion.AnonymousForCertificate;
            binding.EstablishSecurityContext = true;
            binding.RequireDerivedKeys = true;
            binding.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
        }
        else
        {
            binding.LoadPolicy("..\\wse3policyCache.config", "ServerPolicy");
        }
    
        WSSecurityAnonymousServiceSoapClient client = new WSSecurityAnonymousServiceSoapClient(binding, address);
    
    Private Shared Sub CallWseService(ByVal usePolicyFile As Boolean)
    
        Dim address As New EndpointAddress(New Uri("http://localhost/WSSecurityAnonymousPolicy/WSSecurityAnonymousService.asmx"), EndpointIdentity.CreateDnsIdentity("WSE2QuickStartServer"))
    
        Dim binding As New WseHttpBinding()
        If Not usePolicyFile Then
    
            binding.SecurityAssertion = WseSecurityAssertion.AnonymousForCertificate
            binding.EstablishSecurityContext = True
            binding.RequireDerivedKeys = True
            binding.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt
    
        Else
            binding.LoadPolicy("..\wse3policyCache.config", "ServerPolicy")
        End If
    
        Dim client As New WSSecurityAnonymousServiceSoapClient(binding, address)
    

Příklad

Následující příklad kódu definuje vlastní vazbu, která zveřejňuje vlastnosti, které odpovídají vlastnostem WSE 3.0 kontrolní výraz zabezpečení klíče. Vlastní vazba, která je pojmenována WseHttpBinding, se pak použije k určení vlastností vazby pro klienta WCF.

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.ServiceModel.Channels;

namespace Microsoft.ServiceModel.Samples
{
    // The service contract is defined in generatedClient.cs, generated from the service by
    // the svcutil tool.

    class Program
    {
        static void Main(string[] args)
        {
            CallWseService(true);
        }
        static void CallWseService(bool usePolicyFile)
        {
            EndpointAddress address = new EndpointAddress(new Uri("http://localhost/WSSecurityAnonymousPolicy/WSSecurityAnonymousService.asmx"),
                                                          EndpointIdentity.CreateDnsIdentity("WSE2QuickStartServer"));

            WseHttpBinding binding = new WseHttpBinding();
            if (!usePolicyFile)
            {
                binding.SecurityAssertion = WseSecurityAssertion.AnonymousForCertificate;
                binding.EstablishSecurityContext = true;
                binding.RequireDerivedKeys = true;
                binding.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
            }
            else
            {
                binding.LoadPolicy("..\\wse3policyCache.config", "ServerPolicy");
            }

            WSSecurityAnonymousServiceSoapClient client = new WSSecurityAnonymousServiceSoapClient(binding, address);

            // Need to supply the credentials depending on the type of WseSecurityAssertion used.
            // Anonymous only requires server certificate. UsernameForCertificate would also require
            // a username and password to be supplied.
            client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
                                                                 StoreLocation.LocalMachine,
                                                                 StoreName.My,
                                                                 X509FindType.FindBySubjectDistinguishedName,
                                                                 "CN=WSE2QuickStartServer");
            string[] symbols = new string[] { "FABRIKAM", "CONTOSO" };
            StockQuote[] quotes = client.StockQuoteRequest(symbols);

            client.Close();

            // Success!
            foreach (StockQuote quote in quotes)
            {
                Console.WriteLine("");
                Console.WriteLine("Symbol: " + quote.Symbol);
                Console.WriteLine("\tName:\t\t\t" + quote.Name);
                Console.WriteLine("\tLast Price:\t\t" + quote.Last);
                Console.WriteLine("\tPrevious Change:\t" + quote.PreviousChange + "%");
            }

            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
}
Imports System.Collections.Generic
Imports System.Text
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Security
Imports System.ServiceModel.Channels

Namespace Microsoft.ServiceModel.Samples

    ' The service contract is defined in generatedClient.vb, generated from the service by
    ' the svcutil tool.
    Class Program

        Public Shared Sub Main(ByVal args As String())

            CallWseService(True)

        End Sub

        Private Shared Sub CallWseService(ByVal usePolicyFile As Boolean)

            Dim address As New EndpointAddress(New Uri("http://localhost/WSSecurityAnonymousPolicy/WSSecurityAnonymousService.asmx"), EndpointIdentity.CreateDnsIdentity("WSE2QuickStartServer"))

            Dim binding As New WseHttpBinding()
            If Not usePolicyFile Then

                binding.SecurityAssertion = WseSecurityAssertion.AnonymousForCertificate
                binding.EstablishSecurityContext = True
                binding.RequireDerivedKeys = True
                binding.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt

            Else
                binding.LoadPolicy("..\wse3policyCache.config", "ServerPolicy")
            End If

            Dim client As New WSSecurityAnonymousServiceSoapClient(binding, address)

            ' Need to supply the credentials depending on the type of WseSecurityAssertion used.
            ' Anonymous only requires server certificate. UsernameForCertificate would also require
            ' a username and password to be supplied.
            client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=WSE2QuickStartServer")
            Dim symbols As String() = New String() {"FABRIKAM", "CONTOSO"}
            Dim quotes As StockQuote() = client.StockQuoteRequest(symbols)

            client.Close()

            ' Success!
            For Each quote As StockQuote In quotes

                Console.WriteLine("")
                Console.WriteLine("Symbol: " + quote.Symbol)
                Console.WriteLine("" & Chr(9) & "Name:" & Chr(9) & "" & Chr(9) & "" & Chr(9) & "" + quote.Name)
                Console.WriteLine("" & Chr(9) & "Last Price:" & Chr(9) & "" & Chr(9) & "" & quote.Last)
                Console.WriteLine("" & Chr(9) & "Previous Change:" & Chr(9) & "" & quote.PreviousChange & "%")

            Next

            Console.WriteLine("Press <ENTER> to terminate client.")
            Console.ReadLine()

        End Sub

    End Class

End Namespace

Viz také