feign
クライアントでcurl -k
を達成するにはどうすればよいですか?
私はこれができることを知っています。無視または無効にする方法があるかどうかを知りたいだけです。
new Client.Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier)
多くの非常に正当な理由で実際にこれを行うべきではありません。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);
}
}
私はこの答えから大いに借りました:
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
偽の構成によるオーバーライド
@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;
}
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>
Application.yamlに以下のプロパティを追加して、ssl検証を無効にします。
feign.httpclient.disableSslValidation = true
またはVM引数として
-Dfeign.httpclient.disableSslValidation = true