【问题标题】:SSL Certificate in Spring BootSpring Boot 中的 SSL 证书
【发布时间】:2014-11-25 13:57:13
【问题描述】:

我有证书文件 xx.crt 和 xx.pfx。我也有 xx.pfx 的密码。如何配置这个 Spring Boot 嵌入式 tomcat?

    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
    connector.setScheme("https");
    connector.setSecure(true);
    protocol.setSSLEnabled(true);
    protocol.setKeystoreFile(??);
    protocol.setKeyPass(??);
    protocol.setTruststoreFile(??);
    return connector;

【问题讨论】:

    标签: java spring ssl certificate spring-boot


    【解决方案1】:

    在 Spring Boot 中使用 .pfx 文件的最简单方法。
    请按照以下步骤使其工作。
    1) 从服务提供商处获取 pfx 文件。
    2) 安装证书。如何安装证书请参考link。

    application.properties

    server.port= 9091
    server.ssl.trust-store= classpath:jks/Test_Certificate.pfx
    server.ssl.trust-store-password= XXXXXX
    server.ssl.enabled= false
    server.ssl.trust-store-type= PKCS12
    soap.url=https://localost:8080/test/Calculator.wsdl
    

    TestClientConfiguration.java

    import java.io.IOException;
    import java.security.KeyStore;
    
    import javax.net.ssl.SSLContext;
    
    import org.apache.http.HttpException;
    import org.apache.http.HttpRequest;
    import org.apache.http.HttpRequestInterceptor;
    import org.apache.http.client.HttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.protocol.HttpContext;
    import org.apache.http.ssl.SSLContexts;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.Resource;
    import org.springframework.oxm.jaxb.Jaxb2Marshaller;
    import org.springframework.ws.transport.http.HttpComponentsMessageSender;
    
    @Configuration
    public class TestClientConfiguration {
    
        private final String SOAP_URI = "https://localost:8080/test/Calculator.wsdl";
    
        @Value("${server.ssl.trust-store}")
        private Resource trustStore;
    
        @Value("${server.ssl.trust-store-password}")
        private String trustStorePassword;
    
        @Value("${server.ssl.trust-store-type}")
        private String trustStoreType;
    
        @Bean
        public TestServiceClient processMessage(Jaxb2Marshaller marshaller) throws Exception {
            TestServiceClient client = new TestServiceClient();
            client.setDefaultUri(SOAP_URI);
            client.setMarshaller(marshaller);
            client.setUnmarshaller(marshaller);
            client.setMessageSender(httpComponentsMessageSender());
            return client;
        }
    
        @Bean
        Jaxb2Marshaller jaxb2Marshaller() {
            Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
            jaxb2Marshaller.setContextPath("com.test.soap.types");
    
            return jaxb2Marshaller;
        }
    
        @Bean
        public HttpComponentsMessageSender httpComponentsMessageSender() throws Exception {
            HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
            httpComponentsMessageSender.setHttpClient(httpClient());
            return httpComponentsMessageSender;
        }
    
        public HttpClient httpClient() throws Exception {
            KeyStore keyStore = KeyStore.getInstance(trustStoreType);
            keyStore.load(trustStore.getInputStream(), trustStorePassword.toCharArray());
    
            SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, trustStorePassword.toCharArray())
                    .build();
    
            HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext)
                    .addInterceptorFirst(new ContentLengthHeaderRemover()).build();
            return httpClient;
        }
    
    }
    

    TestServiceClient.java

    import java.io.IOException;
    import java.io.StringReader;
    import java.io.StringWriter;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBElement;
    import javax.xml.bind.Marshaller;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
    
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.ws.WebServiceMessage;
    import org.springframework.ws.client.core.WebServiceMessageCallback;
    import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
    import org.springframework.ws.soap.SoapHeader;
    import org.springframework.ws.soap.SoapMessage;
    
    @Qualifier("testSoapServiceClient")
    public class TestServiceClient extends WebServiceGatewaySupport {
        @Value("${soap.url}")
        private String testsoapurl;
    
        public String processMessage(String mgRequest, Message reqHeader) {
    
            StreamSource source = new StreamSource(new StringReader(mgRequest));
            StringWriter stringWriter = new StringWriter();
            StreamResult result = new StreamResult(stringWriter);
            getWebServiceTemplate().sendSourceAndReceiveToResult(testsoapurl, source, new WebServiceMessageCallback() {
    
                @Override
                public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
                    try {
                        SoapMessage soapMessage = (SoapMessage) message;
    
                        //Soap Actio
                        soapMessage.setSoapAction("urn:test/ProcessMessage");
    
                        // get the header from the SOAP message
                        SoapHeader soapHeader = soapMessage.getSoapHeader();
    
                        // create the header element
                        ObjectFactory factory = new ObjectFactory();
                        JAXBElement<Message> headerMessage = factory.createMessage(reqHeader);
    
                        // create a marshaller
                        JAXBContext context = JAXBContext.newInstance(Message.class);
                        Marshaller marshaller = context.createMarshaller();
    
                        // marshal the headers into the specified result
                        marshaller.marshal(headerMessage, soapHeader.getResult());
                    } catch (Exception e) {
                        /////
                    }
                }
    
            }, result);
            return stringWriter.toString();
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      解决此问题最简单的方法是使用 keytool(Windows 上的 keytool.exe)将 PFX 文件转换为 JKS:

      keytool -importkeystore -srckeystore mypfxfile.pfx -srcstoretype pkcs12 -destkeystore newkeystore.jks -deststoretype JKS
      

      并使用protocol.setKeystoreFile() 和protocol.setKeyPass() 加载它。

      【讨论】:

        【解决方案3】:

        如果您查看Http11NioProtocol 这些方法采用字符串参数...无论如何这里是一个相关的问题/答案How can I specify my .keystore file with Spring Boot and Tomcat?

        【讨论】:

        • 我已经阅读了所有文档和 stackoverflow 问题。它部分有效,但是当将证书复制到生产盒时,它会弄乱一些格式并再次给出 IO 异常。这个问题也可以在 stacktrace 上轻松找到。可能是关键应该包括标准文档中的 keytool 转换(下面接受的答案)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-07
        • 2020-02-24
        • 2018-08-18
        • 1970-01-01
        • 2020-01-10
        • 1970-01-01
        • 2018-06-12
        相关资源
        最近更新 更多