Schützen der WFC-basierten Kommunikation für einen DienstSecure WCF-based communications for a service

Sicherheit ist einer der wichtigsten Aspekte der Kommunikation.Security is one of the most important aspects of communication. Das Reliable Services-Anwendungsframework stellt einige fertige Kommunikationsstapel und Tools bereit, die Sie verwenden können, um die Sicherheit zu verbessern.The Reliable Services application framework provides a few prebuilt communication stacks and tools that you can use to improve security. In diesem Artikel erfahren Sie, wie Sie die Sicherheit bei Verwendung von Dienstremoting verbessern können.This article talks about how to improve security when you're using service remoting.

Wir verwenden ein vorhandenes Beispiel, um zu erläutern, wie der WCF-basierte Kommunikationsstapel für Reliable Services eingerichtet wird.We are using an existing example that explains how to set up a WCF-based communication stack for reliable services. Um die Sicherung eines Diensts zu unterstützen, wenn Sie einen WCF-basierten Kommunikationsstapel verwenden, befolgen Sie diese Schritte:To help secure a service when you're using a WCF-based communication stack, follow these steps:

  1. Für den Dienst müssen Sie die Sicherung des WCF-Kommunikationslisteners (WcfCommunicationListener) unterstützen, den Sie erstellen.For the service, you need to help secure the WCF communication listener (WcfCommunicationListener) that you create. Ändern Sie dazu die CreateServiceReplicaListeners -Methode.To do this, modify the CreateServiceReplicaListeners method.

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        return new[]
        {
            new ServiceReplicaListener(
                this.CreateWcfCommunicationListener)
        };
    }
    
    private WcfCommunicationListener<ICalculator> CreateWcfCommunicationListener(StatefulServiceContext context)
    {
       var wcfCommunicationListener = new WcfCommunicationListener<ICalculator>(
            serviceContext:context,
            wcfServiceObject:this,
            // For this example, we will be using NetTcpBinding.
            listenerBinding: GetNetTcpBinding(),
            endpointResourceName:"WcfServiceEndpoint");
    
        // Add certificate details in the ServiceHost credentials.
        wcfCommunicationListener.ServiceHost.Credentials.ServiceCertificate.SetCertificate(
            StoreLocation.LocalMachine,
            StoreName.My,
            X509FindType.FindByThumbprint,
            "9DC906B169DC4FAFFD1697AC781E806790749D2F");
        return wcfCommunicationListener;
    }
    
    private static NetTcpBinding GetNetTcpBinding()
    {
        NetTcpBinding b = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
        b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
        return b;
    }
    
  2. Auf dem Client bleibt die WcfCommunicationClient -Klasse, die wir im vorherigen Beispiel erstellt haben, unverändert.In the client, the WcfCommunicationClient class that was created in the previous example remains unchanged. Sie müssen aber die CreateClientAsync-Methode von WcfCommunicationClientFactory überschreiben:But you need to override the CreateClientAsync method of WcfCommunicationClientFactory:

    public class SecureWcfCommunicationClientFactory<TServiceContract> : WcfCommunicationClientFactory<TServiceContract> where TServiceContract : class
    {
        private readonly Binding clientBinding;
        private readonly object callbackObject;
        public SecureWcfCommunicationClientFactory(
            Binding clientBinding,
            IEnumerable<IExceptionHandler> exceptionHandlers = null,
            IServicePartitionResolver servicePartitionResolver = null,
            string traceId = null,
            object callback = null)
            : base(clientBinding, exceptionHandlers, servicePartitionResolver,traceId,callback)
        {
            this.clientBinding = clientBinding;
            this.callbackObject = callback;
        }
    
        protected override Task<WcfCommunicationClient<TServiceContract>> CreateClientAsync(string endpoint, CancellationToken cancellationToken)
        {
            var endpointAddress = new EndpointAddress(new Uri(endpoint));
            ChannelFactory<TServiceContract> channelFactory;
            if (this.callbackObject != null)
            {
                channelFactory = new DuplexChannelFactory<TServiceContract>(
                this.callbackObject,
                this.clientBinding,
                endpointAddress);
            }
            else
            {
                channelFactory = new ChannelFactory<TServiceContract>(this.clientBinding, endpointAddress);
            }
            // Add certificate details to the ChannelFactory credentials.
            // These credentials will be used by the clients created by
            // SecureWcfCommunicationClientFactory.  
            channelFactory.Credentials.ClientCertificate.SetCertificate(
                StoreLocation.LocalMachine,
                StoreName.My,
                X509FindType.FindByThumbprint,
                "9DC906B169DC4FAFFD1697AC781E806790749D2F");
            var channel = channelFactory.CreateChannel();
            var clientChannel = ((IClientChannel)channel);
            clientChannel.OperationTimeout = this.clientBinding.ReceiveTimeout;
            return Task.FromResult(this.CreateWcfCommunicationClient(channel));
        }
    }
    

    Verwenden Sie SecureWcfCommunicationClientFactory, um einen WCF-Kommunikationsclient (WcfCommunicationClient) zu erstellen.Use SecureWcfCommunicationClientFactory to create a WCF communication client (WcfCommunicationClient). Verwenden Sie den Client, um Dienstmethoden aufzurufen.Use the client to invoke service methods.

    IServicePartitionResolver partitionResolver = ServicePartitionResolver.GetDefault();
    
    var wcfClientFactory = new SecureWcfCommunicationClientFactory<ICalculator>(clientBinding: GetNetTcpBinding(), servicePartitionResolver: partitionResolver);
    
    var calculatorServiceCommunicationClient =  new WcfCommunicationClient(
        wcfClientFactory,
        ServiceUri,
        ServicePartitionKey.Singleton);
    
    var result = calculatorServiceCommunicationClient.InvokeWithRetryAsync(
        client => client.Channel.Add(2, 3)).Result;
    

Lesen Sie als Nächstes den Artikel Web-API mit OWIN in Reliable Services.As a next step, read Web API with OWIN in Reliable Services.