Bezpieczna komunikacja zdalna usługi w usłudze C#
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 z usługą w języku C#. Opiera się on na istniejącym przykładzie , który wyjaśnia, jak skonfigurować komunikacja zdalną dla niezawodnych usług napisanych w języku C#.
Aby ułatwić zabezpieczanie usługi podczas korzystania z komunikacji zdalnie usługi z usługami języka C#, wykonaj następujące kroki:
Utwórz interfejs ,
IHelloWorldStateful
który definiuje metody, które będą dostępne dla zdalnego wywołania procedury w usłudze. Usługa będzie używać elementuFabricTransportServiceRemotingListener
, który jest zadeklarowany wMicrosoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime
przestrzeni nazw. Jest to implementacjaICommunicationListener
, która zapewnia możliwości komunikacji zdalniej.public interface IHelloWorldStateful : IService { Task<string> GetHelloWorld(); } internal class HelloWorldStateful : StatefulService, IHelloWorldStateful { protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[]{ new ServiceReplicaListener( (context) => new FabricTransportServiceRemotingListener(context,this))}; } public Task<string> GetHelloWorld() { return Task.FromResult("Hello World!"); } }
Dodaj ustawienia odbiornika i poświadczenia zabezpieczeń.
Upewnij się, że certyfikat, którego chcesz użyć, aby ułatwić zabezpieczenie komunikacji z usługą, jest zainstalowany na wszystkich węzłach w klastrze.
Uwaga
W węzłach systemu Linux certyfikat musi być obecny jako pliki w formacie PEM w katalogu /var/lib/sfcerts . Aby dowiedzieć się więcej, zobacz Lokalizacja i format certyfikatów X.509 w węzłach systemu Linux.
Istnieją dwa sposoby udostępniania ustawień odbiornika i poświadczeń zabezpieczeń:
Podaj je bezpośrednio w kodzie usługi:
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { FabricTransportRemotingListenerSettings listenerSettings = new FabricTransportRemotingListenerSettings { MaxMessageSize = 10000000, SecurityCredentials = GetSecurityCredentials() }; return new[] { new ServiceReplicaListener( (context) => new FabricTransportServiceRemotingListener(context,this,listenerSettings)) }; } private static SecurityCredentials GetSecurityCredentials() { // Provide certificate details. var x509Credentials = new X509Credentials { FindType = X509FindType.FindByThumbprint, FindValue = "4FEF3950642138446CC364A396E1E881DB76B48C", StoreLocation = StoreLocation.LocalMachine, StoreName = "My", ProtectionLevel = ProtectionLevel.EncryptAndSign }; x509Credentials.RemoteCommonNames.Add("ServiceFabric-Test-Cert"); x509Credentials.RemoteCertThumbprints.Add("9FEF3950642138446CC364A396E1E881DB76B483"); return x509Credentials; }
Podaj je przy użyciu pakietu konfiguracji:
Dodaj nazwaną
TransportSettings
sekcję w pliku settings.xml.<Section Name="HelloWorldStatefulTransportSettings"> <Parameter Name="MaxMessageSize" Value="10000000" /> <Parameter Name="SecurityCredentialsType" Value="X509" /> <Parameter Name="CertificateFindType" Value="FindByThumbprint" /> <Parameter Name="CertificateFindValue" Value="4FEF3950642138446CC364A396E1E881DB76B48C" /> <Parameter Name="CertificateRemoteThumbprints" Value="9FEF3950642138446CC364A396E1E881DB76B483" /> <Parameter Name="CertificateStoreLocation" Value="LocalMachine" /> <Parameter Name="CertificateStoreName" Value="My" /> <Parameter Name="CertificateProtectionLevel" Value="EncryptAndSign" /> <Parameter Name="CertificateRemoteCommonNames" Value="ServiceFabric-Test-Cert" /> </Section>
W takim przypadku
CreateServiceReplicaListeners
metoda będzie wyglądać następująco:protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { new ServiceReplicaListener( (context) => new FabricTransportServiceRemotingListener( context,this,FabricTransportRemotingListenerSettings .LoadFrom("HelloWorldStatefulTransportSettings"))) }; }
Jeśli dodasz sekcję
TransportSettings
w pliku settings.xml ,FabricTransportRemotingListenerSettings
wszystkie ustawienia z tej sekcji zostaną domyślnie załadowane.<!--"TransportSettings" section .--> <Section Name="TransportSettings"> ... </Section>
W takim przypadku
CreateServiceReplicaListeners
metoda będzie wyglądać następująco:protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() { return new[] { return new[]{ new ServiceReplicaListener( (context) => new FabricTransportServiceRemotingListener(context,this))}; }; }
W przypadku wywoływania metod w zabezpieczonej usłudze przy użyciu stosu komunikacji telefonicznej zamiast używania
Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxy
klasy do utworzenia serwera proxy usługi użyj poleceniaMicrosoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory
. Przekaż ciągFabricTransportRemotingSettings
, który zawieraSecurityCredentials
.var x509Credentials = new X509Credentials { FindType = X509FindType.FindByThumbprint, FindValue = "9FEF3950642138446CC364A396E1E881DB76B483", StoreLocation = StoreLocation.LocalMachine, StoreName = "My", ProtectionLevel = ProtectionLevel.EncryptAndSign }; x509Credentials.RemoteCommonNames.Add("ServiceFabric-Test-Cert"); x509Credentials.RemoteCertThumbprints.Add("4FEF3950642138446CC364A396E1E881DB76B48C"); FabricTransportRemotingSettings transportSettings = new FabricTransportRemotingSettings { SecurityCredentials = x509Credentials, }; ServiceProxyFactory serviceProxyFactory = new ServiceProxyFactory( (c) => new FabricTransportServiceRemotingClientFactory(transportSettings)); IHelloWorldStateful client = serviceProxyFactory.CreateServiceProxy<IHelloWorldStateful>( new Uri("fabric:/MyApplication/MyHelloWorldService")); string message = await client.GetHelloWorld();
Jeśli kod klienta jest uruchomiony w ramach usługi, możesz załadować
FabricTransportRemotingSettings
go z pliku settings.xml. Utwórz sekcję HelloWorldClientTransportSettings podobną do kodu usługi, jak pokazano wcześniej. Wprowadź następujące zmiany w kodzie klienta:ServiceProxyFactory serviceProxyFactory = new ServiceProxyFactory( (c) => new FabricTransportServiceRemotingClientFactory(FabricTransportRemotingSettings.LoadFrom("HelloWorldClientTransportSettings"))); IHelloWorldStateful client = serviceProxyFactory.CreateServiceProxy<IHelloWorldStateful>( new Uri("fabric:/MyApplication/MyHelloWorldService")); string message = await client.GetHelloWorld();
Jeśli klient nie jest uruchomiony jako część usługi, możesz utworzyć plik client_name.settings.xml w tej samej lokalizacji, w której znajduje się client_name.exe. Następnie utwórz sekcję TransportSettings w tym pliku.
Podobnie jak w przypadku dodania
TransportSettings
sekcji w settings.xml/client_name.settings.xml klienta,FabricTransportRemotingSettings
domyślnie ładuje wszystkie ustawienia z tej sekcji.W takim przypadku wcześniejszy kod jest jeszcze bardziej uproszczony:
IHelloWorldStateful client = ServiceProxy.Create<IHelloWorldStateful>( new Uri("fabric:/MyApplication/MyHelloWorldService")); string message = await client.GetHelloWorld();
W następnym kroku przeczytaj artykuł Web API with OWIN in Reliable Services (Interfejs API sieci Web z OWIN w usługach Reliable Services).