จะเรียก API ส่วนที่เหลือที่ปลอดภัยโดยใช้ใบรับรองและรหัสผ่าน. pfx ในเทมเพลต Spring Boot Rest ได้อย่างไร [ปิด]

Aug 15 2020

ฉันต้องการเรียกใช้ API ส่วนที่เหลือที่ปลอดภัยภายนอก (เปิดใช้งาน ssl) จากแอปพลิเคชันสปริงบูตของฉัน API ภายนอกสามารถเข้าถึงได้จากบุรุษไปรษณีย์โดยใช้ใบรับรองและรหัสผ่าน. pfx ตอนนี้ฉันต้องการโทรไปยัง api ภายนอกโดยใช้เทมเพลต rest โดยแนบไฟล์. pfx และรหัสผ่านในแต่ละคำขอ

ฉันไม่รู้วิธีเรียกเทมเพลต rest ผ่าน ssl โดยใช้ใบรับรอง pfx ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม.

คำตอบ

2 Hakan54 Aug 15 2020 at 19:30

สิ่งที่คุณต้องทำคือกำหนดค่าไคลเอ็นต์ apache http ที่อยู่เบื้องหลังของเทมเพลตที่เหลือ ด้านล่างนี้คือตัวอย่างการกำหนดค่า:

SSLContext sslContext = ...;

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

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

RestTemplate restTemplate = new RestTemplate(requestFactory);

มีไลบรารีสองสามแห่งที่มีคลาสยูทิลิตี้ / โรงงาน / ตัวสร้างที่ใช้งานง่ายเพื่อช่วยให้คุณสร้าง SSLContext

  • Apache SSLContextBuilder
  • Jetty SslContextFactory
  • SSLContext-Kickstart

อาจมีไลบรารีอื่น ๆ อีกมากมายที่ให้ฟังก์ชันการทำงานที่คล้ายกัน แต่ฉันรู้แค่สามอย่างนี้ โดยวิธีการที่ sslcontext-kickstart เป็นไลบรารีที่ฉันดูแล

ด้านล่างนี้เป็นภาพรวมของสี่วิธีในการโหลดคีย์สโตร์และสร้าง SSLContext Vanilla Java และโดยใช้ไลบรารีทั้งสาม

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

}