Dela via


Säker fjärrkommunikation för tjänster i en C#-tjänst

Säkerhet är en av de viktigaste aspekterna av kommunikation. Reliable Services-programramverket innehåller några fördefinierade kommunikationsstackar och verktyg som du kan använda för att förbättra säkerheten. Den här artikeln beskriver hur du kan förbättra säkerheten när du använder tjänstkommunikation i en C#-tjänst. Den bygger på ett befintligt exempel som förklarar hur du konfigurerar fjärrkommunikation för tillförlitliga tjänster som skrivits i C#.

Följ dessa steg för att skydda en tjänst när du använder tjänstkommunikation med C#-tjänster:

  1. Skapa ett gränssnitt, IHelloWorldStateful, som definierar de metoder som ska vara tillgängliga för ett fjärrproceduranrop på din tjänst. Tjänsten använder FabricTransportServiceRemotingListener, som deklareras i Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime namnområdet. Det här är en ICommunicationListener implementering som tillhandahåller fjärrkommunikationsfunktioner.

    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. Lägg till lyssnarinställningar och säkerhetsautentiseringsuppgifter.

    Kontrollera att certifikatet som du vill använda för att skydda tjänstkommunikationen är installerat på alla noder i klustret.

    Anteckning

    På Linux-noder måste certifikatet finnas som PEM-formaterade filer i katalogen /var/lib/sfcerts . Mer information finns i Plats och format för X.509-certifikat på Linux-noder.

    Du kan ange lyssnarinställningar och säkerhetsautentiseringsuppgifter på två sätt:

    1. Ange dem direkt i tjänstkoden:

      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;
      }
      
    2. Ange dem med hjälp av ett konfigurationspaket:

      Lägg till ett namngivet TransportSettings avsnitt i filen 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>
      

      I det här fallet CreateServiceReplicaListeners ser metoden ut så här:

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          return new[]
          {
              new ServiceReplicaListener(
                  (context) => new FabricTransportServiceRemotingListener(
                      context,this,FabricTransportRemotingListenerSettings .LoadFrom("HelloWorldStatefulTransportSettings")))
          };
      }
      

      Om du lägger till ett TransportSettings avsnitt i filen settings.xml läser FabricTransportRemotingListenerSettings du in alla inställningar från det här avsnittet som standard.

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

      I det här fallet CreateServiceReplicaListeners ser metoden ut så här:

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          return new[]
          {
              return new[]{
                      new ServiceReplicaListener(
                          (context) => new FabricTransportServiceRemotingListener(context,this))};
          };
      }
      
  3. När du anropar metoder på en skyddad tjänst med hjälp av fjärrkommunikationsstacken använder Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactorydu i stället för att använda Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxy klassen för att skapa en tjänstproxy. Skicka in FabricTransportRemotingSettings, som innehåller SecurityCredentials.

    
    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();
    
    

    Om klientkoden körs som en del av en tjänst kan du läsa in FabricTransportRemotingSettings från den settings.xml filen. Skapa ett HelloWorldClientTransportSettings-avsnitt som liknar tjänstkoden, som du visade tidigare. Gör följande ändringar i klientkoden:

    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();
    
    

    Om klienten inte körs som en del av en tjänst kan du skapa en client_name.settings.xml fil på samma plats där client_name.exe finns. Skapa sedan ett TransportSettings-avsnitt i filen.

    Om du lägger till ett TransportSettings avsnitt i klienten settings.xml/client_name.settings.xml FabricTransportRemotingSettings läser du in alla inställningar från det här avsnittet som standard.

    I så fall förenklas den tidigare koden ytterligare:

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

Som ett nästa steg läser du Webb-API med OWIN i Reliable Services.