web-dev-qa-db-ja.com

FeignでSSL証明書の信頼エラーを無視する方法は?

feignクライアントでcurl -kを達成するにはどうすればよいですか?

私はこれができることを知っています。無視または無効にする方法があるかどうかを知りたいだけです。

new Client.Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier)
7
Bee

免責事項

多くの非常に正当な理由で実際にこれを行うべきではありません。SSLの問題を修正する最も簡単な方法は、実際にSSLのベストプラクティスに従い、有効な証明書を使用することです。 。 https://letsencrypt.org/ のような優れたプロジェクトがオンラインにあり、ホストが一般にアクセス可能である場合(検証可能な実際のホスト名がある場合)、無料で優れたセキュリティを取得することもできます。に対して)。

使用ATあなた自身のリスク。あなたが多くのベストプラクティスに違反していることを理解し、それを理解した場合にのみこれを使用してください。

このサンプルコードを使用して何らかの重大な問題を引き起こした場合、あなたは責任を負います。

リアルトーク

Spring-Bootアプリケーションから呼び出したい内部(公的にアクセスできない)サービスを処理するのと同じ問題があり、次のコードを使用して解決しました。

簡単な概要

非常に多くの人が、すべての証明書を受け入れるか、特定の証明書をハードコーディングするか、または他の何かを行うことができると言うでしょう。実際には、コードパスを介して特定の信頼できるホストのみを許可できます。これは、セキュリティの追加レイヤーとしてここで試みていることです。

このサンプルコードでは、複数のホストをクラスに渡すことができ、それらのホストへの要求のみが無効な証明書で発行されるようにする必要があります。それ以外はすべて、通常のコマンドチェーンを通過します。

これは実際には製品グレードのコードではありませんが、うまくいけば、それをある程度利用できるでしょう。

十分な講義を行うと、次のことが最も興味を引くかもしれません。

コード

これは、Java 8およびspring-bootに使用しています。

構成

@Configuration
    public class FeignClientConfiguration {

    @Bean
    public Client client() throws NoSuchAlgorithmException, 
        KeyManagementException {

        return new Client.Default(
            new NaiveSSLSocketFactory("your.Host.here"),
            new NaiveHostnameVerifier("your.Host.here"));
    }
}

NaiveHostnameVerifier

public class NaiveHostnameVerifier implements HostnameVerifier {
    private final Set<String> naivelyTrustedHostnames;

    private final HostnameVerifier hostnameVerifier =
        HttpsURLConnection.getDefaultHostnameVerifier();

    public NaiveHostnameVerifier(String ... naivelyTrustedHostnames) {
        this.naivelyTrustedHostnames =
                Collections.unmodifiableSet(
                    new HashSet<>(Arrays.asList(naivelyTrustedHostnames)));
    }

    @Override
    public boolean verify(String hostname, SSLSession session) {
        return naivelyTrustedHostnames.contains(hostname) ||
                hostnameVerifier.verify(hostname, session);
    }
}

NaiveSSLSocketFactory

public class NaiveSSLSocketFactory extends SSLSocketFactory {
    private final SSLSocketFactory sslSocketFactory = 
                    (SSLSocketFactory) SSLSocketFactory.getDefault();

    private final SSLContext alwaysAllowSslContext;
    private final Set<String> naivelyTrustedHostnames;

    public NaiveSSLSocketFactory(String ... naivelyTrustedHostnames) 
        throws NoSuchAlgorithmException, KeyManagementException {

        this.naivelyTrustedHostnames = 
                Collections.unmodifiableSet(
                    new HashSet<>(Arrays.asList(naivelyTrustedHostnames)));

        alwaysAllowSslContext = SSLContext.getInstance("TLS");
        TrustManager tm = new X509TrustManager() {

            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) 
                throws CertificateException {}

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                    return null;
            }
        };

        alwaysAllowSslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return sslSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return sslSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket socket, String Host, int port, boolean autoClose) throws IOException {
        return (naivelyTrustedHostnames.contains(Host)) 
            ? alwaysAllowSslContext.getSocketFactory().createSocket(socket, Host, port, autoClose) 
            : sslSocketFactory.createSocket(socket, Host, port, autoClose);
    }

    @Override
    public Socket createSocket(String Host, int port) throws IOException, UnknownHostException {
        return (naivelyTrustedHostnames.contains(Host)) 
            ? alwaysAllowSslContext.getSocketFactory().createSocket(Host, port) 
            : sslSocketFactory.createSocket(Host, port);
    }

    @Override
    public Socket createSocket(String Host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
        return (naivelyTrustedHostnames.contains(Host)) 
            ? alwaysAllowSslContext.getSocketFactory().createSocket(Host, port, localAddress, localPort) 
            : sslSocketFactory.createSocket(Host, port, localAddress, localPort);
    }

    @Override
    public Socket createSocket(InetAddress Host, int port) throws IOException {
        return (naivelyTrustedHostnames.contains(Host.getHostName())) 
            ? alwaysAllowSslContext.getSocketFactory().createSocket(Host, port) 
            : sslSocketFactory.createSocket(Host, port);
    }

    @Override
    public Socket createSocket(InetAddress Host, int port, InetAddress localHost, int localPort) throws IOException {
        return (naivelyTrustedHostnames.contains(Host.getHostName())) 
            ? alwaysAllowSslContext.getSocketFactory().createSocket(Host, port, localHost, localPort) 
            : sslSocketFactory.createSocket(Host, port, localHost, localPort);
    }
}

参考文献

私はこの答えから大いに借りました:

HTTPS経由でHttpClientを使用してすべての証明書を信頼する

18
Dan Smith

Spring Cloud Netflix> = 1.4.4.RELEASEを使用する場合は、次のこともできます。

okhttpクライアントMaven依存関係を追加します:

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-okhttp</artifactId>
    </dependency>

そして、次のプロパティを追加します。

feign.httpclient.disableSslValidation=true
feign.httpclient.enabled=false
feign.okhttp.enabled=true

参照: https://github.com/spring-cloud/spring-cloud-netflix/issues/2729

7
Dirk

偽の構成によるオーバーライド

@Bean
public Client feignClient()
{
    Client trustSSLSockets = new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
    return trustSSLSockets;
}


private SSLSocketFactory getSSLSocketFactory() {
    try {
        TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        };

        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
        return sslContext.getSocketFactory();
    } catch (Exception exception) {
    }
    return null;
}
4
eranda.del

feign.httpclient.disableSslValidation = trueは機能しません。

次のコードを使用して、構成でクライアントBeanを作成します。

import feign.Client;
import org.Apache.http.conn.ssl.NoopHostnameVerifier;
import org.Apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.Apache.http.ssl.SSLContexts;
import org.springframework.context.annotation.Bean;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;

public class ClientConfiguration {

    @Bean
    public Client feignClient() {
        return new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
    }

    private SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
            return sslContext.getSocketFactory();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

}

pom.xmlは依存関係を追加する必要があるかもしれません:

    <dependency>
        <groupId>org.Apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.8</version>
    </dependency>
1
wanana

Application.yamlに以下のプロパティを追加して、ssl検証を無効にします。

feign.httpclient.disableSslValidation = true

またはVM引数として

-Dfeign.httpclient.disableSslValidation = true

1
Mohit Sharma