Làm cách nào để gọi api phần còn lại bảo mật bằng chứng chỉ và mật khẩu .pfx trong mẫu phần còn lại khởi động mùa xuân? [đóng cửa]

Aug 15 2020

Tôi cần gọi một api nghỉ ngơi được bảo mật bên ngoài (đã bật ssl) từ ứng dụng khởi động mùa xuân của mình. Có thể truy cập api bên ngoài từ người đưa thư bằng chứng chỉ và mật khẩu .pfx. Bây giờ tôi muốn thực hiện một cuộc gọi đến api bên ngoài bằng cách sử dụng mẫu phần còn lại bằng cách đính kèm tệp .pfx và mật khẩu trên mỗi yêu cầu.

Tôi không biết cách gọi mẫu còn lại qua ssl bằng chứng chỉ pfx. Bất kỳ trợ giúp sẽ được đánh giá cao.

Trả lời

2 Hakan54 Aug 15 2020 at 19:30

Những gì bạn cần làm là định cấu hình máy khách http apache cơ bản của mẫu phần còn lại. Dưới đây là một cấu hình ví dụ:

SSLContext sslContext = ...;

HttpClient httpClient = HttpClients.custom()
    .setSSLContext(sslContext)
    .build();

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);

RestTemplate restTemplate = new RestTemplate(requestFactory);

Có một số thư viện cung cấp các lớp tiện ích / nhà máy / người xây dựng dễ sử dụng để giúp bạn tạo một văn bản SSLContext.

  • Apache SSLContextBuilder
  • Cầu tàu SslContextFactory
  • SSLContext-Kickstart

Có thể có một loạt thư viện khác cung cấp chức năng tương tự, nhưng tôi chỉ biết về ba thư viện này. Nhân tiện, sslcontext-kickstart là một thư viện được duy trì bởi tôi.

Dưới đây là tổng quan về bốn cách để tải kho khóa và tạo một văn bản SSLC. Vanilla Java và bằng cách sử dụng ba thư viện.

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

}