Udostępnij za pośrednictwem


Zabezpiecz komunikację zdalną usług 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. Ten artykuł omawia, jak poprawić bezpieczeństwo podczas korzystania z zdalnego wywoływania usług w usłudze C#. To jest oparte na istniejącym przykładzie, który wyjaśnia, jak skonfigurować zdalne wykonywanie dla niezawodnych usług napisanych w języku C#.

Aby zabezpieczyć usługę podczas korzystania z zdalnego połączenia usługowego w usługach C#, należy wykonać następujące kroki:

  1. Utwórz interfejs, IHelloWorldStateful, który definiuje metody dostępne dla zdalnego wywołania procedury w Twojej usłudze. Twoja usługa będzie korzystać z FabricTransportServiceRemotingListener, który jest zadeklarowany w przestrzeni nazw Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime. This is an ICommunicationListener implementation that provides remoting capabilities.

    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!");
        }
    }
    
  2. Dodaj ustawienia nasłuchiwania i dane uwierzytelniające zabezpieczenia.

    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

    Na węzłach Linux, certyfikat musi być obecny jako pliki sformatowane w 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ń nasłuchiwania i poświadczeń bezpieczeństwa:

    1. 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 = "BB22CC33DD44EE55FF66AA77BB88CC99DD00EE11",
              StoreLocation = StoreLocation.LocalMachine,
              StoreName = "My",
              ProtectionLevel = ProtectionLevel.EncryptAndSign
          };
          x509Credentials.RemoteCommonNames.Add("ServiceFabric-Test-Cert");
          x509Credentials.RemoteCertThumbprints.Add("AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00");
          return x509Credentials;
      }
      
    2. 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="BB22CC33DD44EE55FF66AA77BB88CC99DD00EE11" />
          <Parameter Name="CertificateRemoteThumbprints" Value="AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00" />
          <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 metoda CreateServiceReplicaListeners 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 domyślnie załaduje wszystkie ustawienia z tej sekcji.

      <!--"TransportSettings" section .-->
      <Section Name="TransportSettings">
          ...
      </Section>
      

      W takim przypadku metoda CreateServiceReplicaListeners będzie wyglądać następująco:

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          return new[]
          {
              return new[]{
                      new ServiceReplicaListener(
                          (context) => new FabricTransportServiceRemotingListener(context,this))};
          };
      }
      
  3. When you call methods on a secured service by using the remoting stack, instead of using the Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxy class to create a service proxy, use Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory. Przekaż FabricTransportRemotingSettings, który zawiera SecurityCredentials.

    
    var x509Credentials = new X509Credentials
    {
        FindType = X509FindType.FindByThumbprint,
        FindValue = "AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00",
        StoreLocation = StoreLocation.LocalMachine,
        StoreName = "My",
        ProtectionLevel = ProtectionLevel.EncryptAndSign
    };
    x509Credentials.RemoteCommonNames.Add("ServiceFabric-Test-Cert");
    x509Credentials.RemoteCertThumbprints.Add("BB22CC33DD44EE55FF66AA77BB88CC99DD00EE11");
    
    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 z pliku settings.xml. Utwórz sekcję HelloWorldClientTransportSettings, która jest podobna do kodu serwisowego, 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 uruchamiany jako część usługi, możesz utworzyć plik client_name.settings.xml w tej samej lokalizacji, w której znajduje się plik client_name.exe. Następnie utwórz sekcję TransportSettings w tym pliku.

    Podobnie jak w przypadku usługi, jeśli dodasz sekcję TransportSettings w plikach klienta settings.xml/client_name.settings.xml, FabricTransportRemotingSettings domyślnie ładuje wszystkie ustawienia z tej sekcji.

    W takim przypadku wcześniejszy kod zostaje jeszcze bardziej uproszczony:

    
    IHelloWorldStateful client = ServiceProxy.Create<IHelloWorldStateful>(
                 new Uri("fabric:/MyApplication/MyHelloWorldService"));
    
    string message = await client.GetHelloWorld();
    
    

Jako następny krok, przeczytaj Web API with OWIN in Reliable Services.