Comunicações remotas de serviço segura num serviço Java
A segurança é um dos aspetos mais importantes da comunicação. A arquitetura da aplicação Reliable Services fornece algumas pilhas e ferramentas de comunicação pré-criadas que pode utilizar para melhorar a segurança. Este artigo aborda como melhorar a segurança quando está a utilizar a comunicação remota do serviço num serviço Java. Baseia-se num exemplo existente que explica como configurar a comunicação remota para serviços fiáveis escritos em Java.
Para ajudar a proteger um serviço quando estiver a utilizar a comunicação remota do serviço com serviços Java, siga estes passos:
Crie uma interface,
HelloWorldStateless
, que defina os métodos que estarão disponíveis para uma chamada de procedimento remoto no seu serviço. O seu serviço utilizaráFabricTransportServiceRemotingListener
, que é declarado nomicrosoft.serviceFabric.services.remoting.fabricTransport.runtime
pacote. Esta é uma implementaçãoCommunicationListener
que fornece capacidades remotas.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!"); } }
Adicione as definições do serviço de escuta e as credenciais de segurança.
Certifique-se de que o certificado que pretende utilizar para ajudar a proteger a comunicação do serviço está instalado em todos os nós do cluster. Para serviços em execução no Linux, o certificado tem de estar disponível como um ficheiro com formato PEM; um
.pem
ficheiro que contenha o certificado e a chave privada ou um.crt
ficheiro que contenha o certificado e um.key
ficheiro que contenha a chave privada. Para saber mais, veja Localização e formato dos certificados X.509 nos nós do Linux.Existem duas formas de fornecer as definições do serviço de escuta e as credenciais de segurança:
Forneça-os através de um pacote de configuração:
Adicione uma secção com nome
TransportSettings
no ficheiro 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/BD1C71E248B8C6834C151174DECDBDC02DE1D954.crt" /> <Parameter Name="CertificateProtectionLevel" Value="EncryptandSign" /> <Parameter Name="CertificateRemoteThumbprints" Value="BD1C71E248B8C6834C151174DECDBDC02DE1D954" /> </Section>
Neste caso, o método terá o
createServiceInstanceListeners
seguinte aspeto: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 adicionar uma
TransportSettings
secção no ficheiro settings.xml sem qualquer prefixo,FabricTransportListenerSettings
carregará todas as definições desta secção por predefinição.<!--"TransportSettings" section without any prefix.--> <Section Name="TransportSettings"> ... </Section>
Neste caso, o método terá o
CreateServiceInstanceListeners
seguinte aspeto:protected List<ServiceInstanceListener> createServiceInstanceListeners() { ArrayList<ServiceInstanceListener> listeners = new ArrayList<>(); listeners.add(new ServiceInstanceListener((context) -> { return new FabricTransportServiceRemotingListener(context,this); })); return listeners; }
Quando chamar métodos num serviço seguro através da pilha remota, em vez de utilizar a
microsoft.serviceFabric.services.remoting.client.ServiceProxyBase
classe para criar um proxy de serviço, utilizemicrosoft.serviceFabric.services.remoting.client.FabricServiceProxyFactory
.Se o código de cliente estiver em execução como parte de um serviço, pode carregar
FabricTransportSettings
a partir do ficheiro de settings.xml. Crie uma secção TransportSettings semelhante ao código de serviço, conforme mostrado anteriormente. Efetue as seguintes alterações ao código de cliente: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();