Delen via


Procedure: Toegang krijgen tot een WSE 3.0-service met een WCF-client

WCF-clients (Windows Communication Foundation) zijn wire-level compatibel met WSE (Web Services Enhancements) 3.0 voor Microsoft .NET-services wanneer WCF-clients zijn geconfigureerd voor gebruik van de WS-Adresseringsspecificatie van augustus 2004. WSE 3.0-services bieden echter geen ondersteuning voor het protocol voor metagegevensuitwisseling (MEX), dus wanneer u het Hulpprogramma voor metagegevens van ServiceModel (Svcutil.exe) gebruikt om een WCF-clientklasse te maken, worden de beveiligingsinstellingen niet toegepast op de gegenereerde WCF-client. Daarom moet u de beveiligingsinstellingen opgeven die de WSE 3.0-service vereist nadat de WCF-client is gegenereerd.

U kunt deze beveiligingsinstellingen toepassen met behulp van een aangepaste binding om rekening te houden met de WSE 3.0-servicevereisten en de interoperabele vereisten tussen een WSE 3.0-service en een WCF-client. Deze interoperabiliteitsvereisten omvatten het bovengenoemde gebruik van de WS-Adresseringsspecificatie van augustus 2004 en de WSE 3.0default-berichtbeveiliging van SignBeforeEncrypt. De standaardberichtbeveiliging voor WCF is SignBeforeEncryptAndEncryptSignature. In dit onderwerp wordt beschreven hoe u een WCF-binding maakt die interoperateert met een WSE 3.0-service. WCF biedt ook een voorbeeld waarin deze binding wordt opgenomen. Zie Samenwerken met ASMX-webservices voor meer informatie over dit voorbeeld.

Toegang krijgen tot een WSE 3.0-webservice met een WCF-client

  1. Voer het hulpprogramma Voor metagegevens van ServiceModel (Svcutil.exe) uit om een WCF-client te maken voor de WSE 3.0-webservice.

    Voor een WSE 3.0-webservice wordt een WCF-client gemaakt. Omdat WSE 3.0 het MEX-protocol niet ondersteunt, kunt u het hulpprogramma niet gebruiken om de beveiligingsvereisten voor de webservice op te halen. De ontwikkelaar van de toepassing moet de beveiligingsinstellingen voor de client toevoegen.

    Zie de procedure: Een client maken voor meer informatie over het maken van een WCF-client.

  2. Maak een klasse die een binding vertegenwoordigt die kan communiceren met WSE 3.0-webservices.

    De volgende klasse maakt deel uit van de interoperating met WSE-voorbeeld :

    1. Maak een klasse die is afgeleid van de Binding klasse.

      In het volgende codevoorbeeld wordt een klasse gemaakt WseHttpBinding die is afgeleid van de Binding klasse.

      public class WseHttpBinding : Binding
      {
      
      Public Class WseHttpBinding
          Inherits Binding
      
    2. Voeg eigenschappen toe aan de klasse die de kant-en-klare WSE-assertie opgeeft die wordt gebruikt door de WSE-service, of afgeleide sleutels vereist zijn, of beveiligde sessies worden gebruikt, of handtekeningbevestigingen vereist zijn en de instellingen voor berichtbeveiliging. In WSE 3.0 geeft een kant-en-klare assertie de beveiligingsvereisten voor een client of webservice aan, vergelijkbaar met de verificatiemodus van een binding in WCF.

      In het volgende codevoorbeeld worden de SecurityAssertioneigenschappen , RequireDerivedKeysen EstablishSecurityContexteigenschappen gedefinieerd waarmee de WSE-kant-en-klare MessageProtectionOrder sleutel wordt opgegeven, of afgeleide sleutels vereist zijn, of beveiligde sessies worden gebruikt, of handtekeningbevestigingen vereist zijn, en de instellingen voor berichtbeveiliging.

      
      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. Overschrijf de CreateBindingElements methode om de bindingseigenschappen in te stellen.

      In het volgende codevoorbeeld worden de instellingen voor transport, berichtcodering en berichtbeveiliging opgegeven door de waarden van de SecurityAssertion en MessageProtectionOrder eigenschappen op te halen.

      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. Voeg in de code van de clienttoepassing code toe om de bindingseigenschappen in te stellen.

    In het volgende codevoorbeeld wordt aangegeven dat de WCF-client berichtbeveiliging en -verificatie moet gebruiken zoals gedefinieerd door de kant-en-klare WSE 3.0-beveiligingsverklaring AnonymousForCertificate . Daarnaast zijn beveiligde sessies en afgeleide sleutels vereist.

    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)
    

Opmerking

In het volgende codevoorbeeld wordt een aangepaste binding gedefinieerd waarmee eigenschappen worden weergegeven die overeenkomen met de eigenschappen van een kant-en-klare WSE 3.0-beveiligingsverklaring. Deze aangepaste binding, die een naam WseHttpBindingheeft, wordt vervolgens gebruikt om de bindingseigenschappen op te geven voor een WCF-client die communiceert met het WSE 3.0 QuickStart-voorbeeld.

Zie ook