Como chamar a API de descanso seguro usando o certificado e a senha .pfx no modelo de descanso de inicialização do Spring? [fechadas]
Preciso invocar uma API de descanso protegida externa (SSL habilitado) do meu aplicativo de inicialização do Spring. A API externa pode ser acessada pelo carteiro usando o certificado e a senha .pfx. Agora, gostaria de fazer uma chamada para a API externa usando o modelo rest, anexando arquivo .pfx e senha em cada solicitação.
Eu não sei como fazer o modelo de descanso chamar SSL usando o certificado pfx. Qualquer ajuda será apreciada.
Respostas
O que você precisa fazer é configurar o cliente http apache subjacente do modelo rest. Abaixo está um exemplo de configuração:
SSLContext sslContext = ...;
HttpClient httpClient = HttpClients.custom()
    .setSSLContext(sslContext)
    .build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
Existem algumas bibliotecas que fornecem classes de utilitário / fábrica / construtor fáceis de usar para ajudá-lo a criar um SSLContext.
- Apache SSLContextBuilder
- Jetty SslContextFactory
- SSLContext-Kickstart
Pode haver um monte de outras bibliotecas que fornecem funcionalidade semelhante, mas estou ciente apenas dessas três. A propósito, o sslcontext-kickstart é uma biblioteca que é mantida por mim.
Abaixo está uma visão geral das quatro maneiras de carregar os keystores e criar um SSLContext. Vanilla Java e usando as três bibliotecas.
import io.netty.handler.ssl.SslContextBuilder;
import nl.altindag.ssl.SSLFactory;
import org.apache.http.ssl.SSLContextBuilder;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import javax.net.ssl.*;
import java.io.File;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Objects;
class SslExample {
    public static void main(String[] args) throws Exception {
        //creating sslContext with sslcontext-kickstart
        SSLFactory sslFactory = SSLFactory.builder()
                .withIdentityMaterial("keystore.pfx", "secret".toCharArray())
                .withTrustMaterial("truststore.pfx", "secret".toCharArray())
                .build();
        SSLContext sslContext = sslFactory.getSslContext();
        //Traditional flow of creating sslContext
        String keyStorePath = "keystore.pfx";
        String trustStorePath = "truststore.pfx";
        char[] keyStorePassword = "secret".toCharArray();
        char[] trustStorePassword = "secret".toCharArray();
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        KeyStore trustStore = KeyStore.getInstance("PKCS12");
        try(InputStream keyStoreInputStream = SslExample.class.getClassLoader().getResourceAsStream(keyStorePath);
            InputStream trustStoreInputStream = SslExample.class.getClassLoader().getResourceAsStream(trustStorePath)) {
            Objects.requireNonNull(keyStoreInputStream);
            Objects.requireNonNull(trustStoreInputStream);
            keyStore.load(keyStoreInputStream, keyStorePassword);
            trustStore.load(trustStoreInputStream, trustStorePassword);
        }
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, keyStorePassword);
        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        SSLContext sslContext1 = SSLContext.getInstance("TLSv1.2");
        sslContext.init(keyManagers, trustManagers, new SecureRandom());
        //creating sslContext with Apache SSLContextBuilder
        SSLContext sslContext2 = SSLContextBuilder.create()
                .loadKeyMaterial(new File("keystore.pfx"), "secret".toCharArray(), "secret".toCharArray())
                .loadTrustMaterial(new File("truststore.pfx"), "secret".toCharArray())
                .build();
        //creating sslContext with Jetty SslContextFactory
        SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
        sslContextFactory.setKeyStorePath("keystore.pfx");
        sslContextFactory.setKeyStorePassword("secret");
        sslContextFactory.setTrustStorePath("truststore.pfx");
        sslContextFactory.setTrustStorePassword("secret");
        sslContextFactory.start();
        SSLContext sslContext3 = sslContextFactory.getSslContext();
    }
}