Proteggere le comunicazioni remote per Reliable Services in un servizio JavaSecure service remoting communications in a Java service

La sicurezza è uno degli aspetti essenziali delle comunicazioni.Security is one of the most important aspects of communication. Il framework di applicazioni di Reliable Services offre alcuni stack e strumenti predefiniti che è possibile usare per migliorare la sicurezza.The Reliable Services application framework provides a few prebuilt communication stacks and tools that you can use to improve security. Questo articolo discute come migliorare la sicurezza quando si usa la comunicazione remota in un servizio Java.This article discusses how to improve security when you're using service remoting in a Java service. Verrà usato un esempio esistente che spiega come configurare la comunicazione remota per Reliable Services in Java.It builds on an existing example that explains how to set up remoting for reliable services written in Java.

Per proteggere un servizio quando si usa la comunicazione remota con i servizi Java, seguire questa procedura:To help secure a service when you're using service remoting with Java services, follow these steps:

  1. Creare un'interfaccia, HelloWorldStateless, che definisce i metodi che saranno disponibili per la Remote Procedure Call del servizio.Create an interface, HelloWorldStateless, that defines the methods that will be available for a remote procedure call on your service. Il servizio userà il metodo FabricTransportServiceRemotingListener, dichiarato nel pacchetto microsoft.serviceFabric.services.remoting.fabricTransport.runtime.Your service will use FabricTransportServiceRemotingListener, which is declared in the microsoft.serviceFabric.services.remoting.fabricTransport.runtime package. Si tratta di un’implementazione CommunicationListener che fornisce funzionalità di accesso remoto.This is an CommunicationListener implementation that provides remoting capabilities.

    public interface HelloWorldStateless extends Service {
        CompletableFuture<String> getHelloWorld();
    }
    
    class HelloWorldStatelessImpl extends StatelessService implements HelloWorldStateless {
        @Override
        protected List<ServiceInstanceListener> createServiceInstanceListeners() {
            ArrayList<ServiceInstanceListener> listeners = new ArrayList<>();
            listeners.add(new ServiceInstanceListener((context) -> {
                return new FabricTransportServiceRemotingListener(context,this);
            }));
        return listeners;
        }
    
        public CompletableFuture<String> getHelloWorld() {
            return CompletableFuture.completedFuture("Hello World!");
        }
    }
    
  2. Aggiungere le impostazioni del listener e le credenziali di sicurezza.Add listener settings and security credentials.

    Assicurarsi che il certificato da usare per proteggere le comunicazioni dei servizi sia installato in tutti i nodi del cluster.Make sure the certificate that you want to use to help secure your service communication is installed on all the nodes in the cluster. Per i servizi in esecuzione su Linux, il certificato deve essere disponibile come file formattato PEM; un file .pem che contiene il certificato e la chiave privata o un file .crt che contiene il certificato e un file .key che contiene la chiave privata.For services running on Linux, the certificate must be available as a PEM-formmatted file; either a .pem file that contains the certificate and private key or a .crt file that contains the certificate and a .key file that contains the private key. Per altre informazioni, vedere Percorso e formato dei certificati X.509 nei nodi Linux.To learn more, see Location and format of X.509 certificates on Linux nodes.

    Esistono due modi per specificare le impostazioni del listener e le credenziali di sicurezza:There are two ways that you can provide listener settings and security credentials:

    1. Specificarle tramite un pacchetto di configurazione:Provide them by using a config package:

      Aggiungere una sezione denominata TransportSettings nel file settings.xml.Add a named TransportSettings section in the settings.xml file.

      <!--Section name should always end with "TransportSettings".-->
      <!--Here we are using a prefix "HelloWorldStateless".-->
       <Section Name="HelloWorldStatelessTransportSettings">
           <Parameter Name="MaxMessageSize" Value="10000000" />
           <Parameter Name="SecurityCredentialsType" Value="X509_2" />
           <Parameter Name="CertificatePath" Value="/path/to/cert/BD1C71E248B8C6834C151174DECDBDC02DE1D954.crt" />
           <Parameter Name="CertificateProtectionLevel" Value="EncryptandSign" />
           <Parameter Name="CertificateRemoteThumbprints" Value="BD1C71E248B8C6834C151174DECDBDC02DE1D954" />
       </Section>
      

      In questo caso il metodo createServiceInstanceListeners avrà un aspetto analogo al seguente:In this case, the createServiceInstanceListeners method will look like this:

       protected List<ServiceInstanceListener> createServiceInstanceListeners() {
           ArrayList<ServiceInstanceListener> listeners = new ArrayList<>();
           listeners.add(new ServiceInstanceListener((context) -> {
               return new FabricTransportServiceRemotingListener(context,this, FabricTransportRemotingListenerSettings.loadFrom(HelloWorldStatelessTransportSettings));
           }));
           return listeners;
       }
      

      Se si aggiunge una sezione TransportSettings al file settings.xml senza alcun prefisso, FabricTransportListenerSettings caricherà tutte le impostazioni da questa sezione per impostazione predefinita.If you add a TransportSettings section in the settings.xml file without any prefix, FabricTransportListenerSettings will load all the settings from this section by default.

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

      In questo caso il metodo CreateServiceInstanceListeners avrà un aspetto analogo al seguente:In this case, the CreateServiceInstanceListeners method will look like this:

      protected List<ServiceInstanceListener> createServiceInstanceListeners() {
          ArrayList<ServiceInstanceListener> listeners = new ArrayList<>();
          listeners.add(new ServiceInstanceListener((context) -> {
              return new FabricTransportServiceRemotingListener(context,this);
          }));
          return listeners;
      }
      
  3. Quando si chiamano metodi in un servizio protetto tramite lo stack di comunicazione remota, anziché usare la classe microsoft.serviceFabric.services.remoting.client.ServiceProxyBase per creare un proxy del servizio, usare microsoft.serviceFabric.services.remoting.client.FabricServiceProxyFactory.When you call methods on a secured service by using the remoting stack, instead of using the microsoft.serviceFabric.services.remoting.client.ServiceProxyBase class to create a service proxy, use microsoft.serviceFabric.services.remoting.client.FabricServiceProxyFactory.

    Se il codice client viene eseguito come parte del servizio, è possibile caricare FabricTransportSettings dal file settings.xml.If the client code is running as part of a service, you can load FabricTransportSettings from the settings.xml file. Creare una sezione TransportSettings simile al codice del servizio, come illustrato in precedenza.Create a TransportSettings section that is similar to the service code, as shown earlier. Apportare le modifiche seguenti al codice client:Make the following changes to the client code:

    
    FabricServiceProxyFactory serviceProxyFactory = new FabricServiceProxyFactory(c -> {
            return new FabricTransportServiceRemotingClientFactory(FabricTransportRemotingSettings.loadFrom("TransportPrefixTransportSettings"), null, null, null, null);
        }, null)
    
    HelloWorldStateless client = serviceProxyFactory.createServiceProxy(HelloWorldStateless.class,
        new URI("fabric:/MyApplication/MyHelloWorldService"));
    
    CompletableFuture<String> message = client.getHelloWorld();