让 wiremock 接受任何证书

Make wiremock accept any certificate

我在 wiremock 中定义了一个 https 存根,如下所示:-

public class HttpsMockMain {
    public static void main(String[] args) {
        WireMockServer mockServer = new WireMockServer(56789, 8443);
            addStub(mockServer);
            mockServer.start();
    }
    private static void addStub(WireMockServer mockServer) {
        ResponseDefinitionBuilder responseBuilder = aResponse().withStatus(200).withBody(
        "{\"message\":null,\"httpStatus\":0,\"status\":{\"httpStatusCode\":200,\"success\":true,\"errors\":[]},\"_metaData\":{\"urlParams\":{}},\"debugData\":null,\"data\":[\"01125851014\",\"01125851014\",\"debraj.manna@jabong.com\",\"03325853088\",\"03325853088\",\"debraj.manna@rediffmail.com\"],\"httpStatusToBeReturned\":200}");
        mockServer.stubFor(post(urlPathEqualTo("/oms-api/")).willReturn(responseBuilder));
    }
}

每当我向 https://localhost:8443/oms-api/ 发送 POST 请求时,我都会收到以下异常:-

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

是否可以告诉 WireMock 接受任何证书?我在 wiremock 1.58java 1.8.

正如所讨论的 here,问题不在 Wiremock 端,而是客户端代码拒绝了 WireMock 的自签名证书(这是正确的,因为客户端未配置为使用 Wiremock 证书。)。

我看到你在 WireMock github 页面和此处交叉发布。好的,我就把它放在这里。

我在 WireMock 的文档中看到了这个:http://wiremock.org/docs/https/

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

You are using WireMock’s default (self-signed) TLS certificate or another certificate that isn’t signed by a CA. In this case you need to specifically configure your HTTP client to trust the certificate being presented, or to trust all certificates. Here is an example of how to do this with the Apache HTTP client.

link中的示例:

/*
 * Copyright (C) 2011 Thomas Akehurst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.tomakehurst.wiremock.http;

import com.github.tomakehurst.wiremock.common.KeyStoreSettings;
import com.github.tomakehurst.wiremock.common.ProxySettings;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.ProxyAuthenticationStrategy;

import javax.net.ssl.SSLContext;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
import static com.github.tomakehurst.wiremock.common.KeyStoreSettings.NO_STORE;
import static com.github.tomakehurst.wiremock.common.LocalNotifier.notifier;
import static com.github.tomakehurst.wiremock.common.ProxySettings.NO_PROXY;
import static com.github.tomakehurst.wiremock.http.RequestMethod.*;
import static org.apache.commons.lang3.StringUtils.isEmpty;

public class HttpClientFactory {

    public static final int DEFAULT_MAX_CONNECTIONS = 50;
    public static final int DEFAULT_TIMEOUT = 30000;

    public static CloseableHttpClient createClient(
            int maxConnections,
            int timeoutMilliseconds,
            ProxySettings proxySettings,
            KeyStoreSettings trustStoreSettings) {

        HttpClientBuilder builder = HttpClientBuilder.create()
                .disableAuthCaching()
                .disableAutomaticRetries()
                .disableCookieManagement()
                .disableRedirectHandling()
                .disableContentCompression()
                .setMaxConnTotal(maxConnections)
                .setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build())
                .setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(timeoutMilliseconds).build())
                .useSystemProperties()
                .setHostnameVerifier(new AllowAllHostnameVerifier());

        if (proxySettings != NO_PROXY) {
            HttpHost proxyHost = new HttpHost(proxySettings.host(), proxySettings.port());
            builder.setProxy(proxyHost);
            if(!isEmpty(proxySettings.getUsername()) && !isEmpty(proxySettings.getPassword())) {
                builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
                BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                credentialsProvider.setCredentials(
                        new AuthScope(proxySettings.host(), proxySettings.port()),
                        new UsernamePasswordCredentials(proxySettings.getUsername(), proxySettings.getPassword()));
                builder.setDefaultCredentialsProvider(credentialsProvider);
            }
        }

        if (trustStoreSettings != NO_STORE) {
            builder.setSslcontext(buildSSLContextWithTrustStore(trustStoreSettings));
        } else {
            builder.setSslcontext(buildAllowAnythingSSLContext());
        }

        return builder.build();
    }

    private static SSLContext buildSSLContextWithTrustStore(KeyStoreSettings trustStoreSettings) {
        try {
            KeyStore trustStore = trustStoreSettings.loadStore();
            return SSLContexts.custom()
                    .loadTrustMaterial(null, new TrustSelfSignedStrategy())
                    .loadKeyMaterial(trustStore, trustStoreSettings.password().toCharArray())
                    .useTLS()
                    .build();
        } catch (Exception e) {
            return throwUnchecked(e, SSLContext.class);
        }
    }

    private static SSLContext buildAllowAnythingSSLContext() {
        try {
            return SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
        } catch (Exception e) {
            return throwUnchecked(e, SSLContext.class);
        }
    }

    public static CloseableHttpClient createClient(int maxConnections, int timeoutMilliseconds) {
        return createClient(maxConnections, timeoutMilliseconds, NO_PROXY, NO_STORE);
    }

    public static CloseableHttpClient createClient(int timeoutMilliseconds) {
        return createClient(DEFAULT_MAX_CONNECTIONS, timeoutMilliseconds);
    }

    public static CloseableHttpClient createClient(ProxySettings proxySettings) {
        return createClient(DEFAULT_MAX_CONNECTIONS, DEFAULT_TIMEOUT, proxySettings, NO_STORE);
    }

    public static CloseableHttpClient createClient() {
      return createClient(DEFAULT_TIMEOUT);
    }

    public static HttpUriRequest getHttpRequestFor(RequestMethod method, String url) {
        notifier().info("Proxying: " + method + " " + url);

        if (method.equals(GET))
            return new HttpGet(url);
        else if (method.equals(POST))
            return new HttpPost(url);
        else if (method.equals(PUT))
            return new HttpPut(url);
        else if (method.equals(DELETE))
            return new HttpDelete(url);
        else if (method.equals(HEAD))
            return new HttpHead(url);
        else if (method.equals(OPTIONS))
            return new HttpOptions(url);
        else if (method.equals(TRACE))
            return new HttpTrace(url);
        else if (method.equals(PATCH))
            return new HttpPatch(url);
        else
            return new GenericHttpUriRequest(method.toString(), url);
    }
}