Zabezpieczanie komunikacji opartej na programie WCF dla usługi
Bezpieczeństwo jest jednym z najważniejszych aspektów komunikacji. Struktura aplikacji Reliable Services udostępnia kilka wstępnie utworzonych stosów komunikacyjnych i narzędzi, których można użyć do poprawy bezpieczeństwa. W tym artykule omówiono sposób poprawiania zabezpieczeń podczas korzystania z komunikacji zdalnie usługi.
Używamy istniejącego przykładu , który wyjaśnia, jak skonfigurować stos komunikacji opartej na technologii WCF dla niezawodnych usług. Aby zabezpieczyć usługę w przypadku korzystania z stosu komunikacji opartego na technologii WCF, wykonaj następujące kroki:
W przypadku usługi należy zabezpieczyć utworzony odbiornik komunikacji WCF (
WcfCommunicationListener
). W tym celu zmodyfikuj metodęCreateServiceReplicaListeners
.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; }
W kliencie
WcfCommunicationClient
klasa utworzona w poprzednim przykładzie pozostaje niezmieniona. Należy jednak zastąpić metodęCreateClientAsync
: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)); } }
Użyj
SecureWcfCommunicationClientFactory
polecenia , aby utworzyć klienta komunikacji WCF (WcfCommunicationClient
). Użyj klienta do wywoływania metod usługi.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;
W następnym kroku przeczytaj artykuł Web API with OWIN in Reliable Services (Interfejs API sieci Web z OWIN w usługach Reliable Services).