Безопасная удаленная коммуникация в службе Java

Безопасность является одним из наиболее важных аспектов взаимодействия. Платформа приложений Reliable Services предоставляет несколько готовых стеков взаимодействия и средств, которыми можно воспользоваться для повышения безопасности. В этой статье рассматриваются способы повышения безопасности при использовании удаленного вызова служб в Java-сервисе. Он основан на существующем примере , который объясняет, как настроить удаленное взаимодействие для надежных служб, написанных на Java.

Чтобы защитить службу при удаленном вызове с использованием Java-служб, выполните следующие действия.

  1. Создайте интерфейс HelloWorldStateless, определяющий методы, доступные для удаленного вызова процедур в вашей службе. Ваша служба будет использовать FabricTransportServiceRemotingListener, который объявлен в пакете microsoft.serviceFabric.services.remoting.fabricTransport.runtime. Это CommunicationListener реализация, которая предоставляет возможности удаленного доступа.

    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. Добавьте параметры прослушивателя и учетные данные безопасности.

    Убедитесь, что сертификат, который вы хотите использовать для защиты связи со службой, установлен на всех узлах в кластере. Для служб, работающих в Linux, сертификат должен быть доступен в виде файла PEM-formmatted; .pem файл, содержащий сертификат и закрытый ключ, или .crt файл, содержащий сертификат и .key файл, содержащий закрытый ключ. Дополнительные сведения см. в разделе "Расположение и формат сертификатов X.509" на узлах Linux.

    Существует два способа предоставления параметров прослушивателя и учетных данных безопасности.

    1. Предоставьте их с помощью пакета конфигурации:

      Добавьте именованный TransportSettings раздел в файл settings.xml.

      <!--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/AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00.crt" />
           <Parameter Name="CertificateProtectionLevel" Value="EncryptandSign" />
           <Parameter Name="CertificateRemoteThumbprints" Value="AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00" />
       </Section>
      
      

      В этом случае createServiceInstanceListeners метод будет выглядеть следующим образом:

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

      Если добавить TransportSettings раздел в файл settings.xml без префикса, FabricTransportListenerSettings все параметры из этого раздела будут загружены по умолчанию.

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

      В этом случае CreateServiceInstanceListeners метод будет выглядеть следующим образом:

      protected List<ServiceInstanceListener> createServiceInstanceListeners() {
          ArrayList<ServiceInstanceListener> listeners = new ArrayList<>();
          listeners.add(new ServiceInstanceListener((context) -> {
              return new FabricTransportServiceRemotingListener(context,this);
          }));
          return listeners;
      }
      
  3. При вызове методов в защищенной службе с помощью стека удаленного взаимодействия вместо использования класса microsoft.serviceFabric.services.remoting.client.ServiceProxyBase для создания прокси-сервера службы используйте microsoft.serviceFabric.services.remoting.client.FabricServiceProxyFactory.

    Если клиентский код выполняется как часть службы, можно загрузить FabricTransportSettings из файла settings.xml. Создайте раздел TransportSettings, аналогичный коду службы, как показано ранее. Внесите следующие изменения в код клиента:

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