Вот некоторый код, который даст вам общую идею.
Чтобы доверять сертификату, вам необходимо создать пользовательскую форму ClientHttpRequestFactory
. Это выглядит следующим образом:
final ClientHttpRequestFactory clientHttpRequestFactory =
new MyCustomClientHttpRequestFactory(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER, serverInfo);
restTemplate.setRequestFactory(clientHttpRequestFactory);
Это реализация для MyCustomClientHttpRequestFactory
:
public class MyCustomClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
private final HostnameVerifier hostNameVerifier;
private final ServerInfo serverInfo;
public MyCustomClientHttpRequestFactory (final HostnameVerifier hostNameVerifier,
final ServerInfo serverInfo) {
this.hostNameVerifier = hostNameVerifier;
this.serverInfo = serverInfo;
}
@Override
protected void prepareConnection(final HttpURLConnection connection, final String httpMethod)
throws IOException {
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection) connection).setHostnameVerifier(hostNameVerifier);
((HttpsURLConnection) connection).setSSLSocketFactory(initSSLContext()
.getSocketFactory());
}
super.prepareConnection(connection, httpMethod);
}
private SSLContext initSSLContext() {
try {
System.setProperty("https.protocols", "TLSv1");
// Set ssl trust manager. Verify against our server thumbprint
final SSLContext ctx = SSLContext.getInstance("TLSv1");
final SslThumbprintVerifier verifier = new SslThumbprintVerifier(serverInfo);
final ThumbprintTrustManager thumbPrintTrustManager =
new ThumbprintTrustManager(null, verifier);
ctx.init(null, new TrustManager[] { thumbPrintTrustManager }, null);
return ctx;
} catch (final Exception ex) {
LOGGER.error(
"An exception was thrown while trying to initialize HTTP security manager.", ex);
return null;
}
}
В этом случае мой serverInfo
объект содержит отпечаток сервера. Вам необходимо реализовать интерфейс TrustManager
, чтобы получить SslThumbprintVerifier
или любым другим способом, который вы хотите проверить на свой сертификат (вы также можете также вернуть true
).
Значение org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
позволяет использовать все имена хостов. Если вам нужно подтвердить имя хоста, , вам нужно будет реализовать его по-разному.
Я не уверен насчет пользователя и пароля и как вы его реализовали. Часто, необходимо добавить заголовок к restTemplate
с именем Authorization
со значением, которое выглядит так: Base: <encoded user+password>
. user+password
должен быть закодирован Base64
.
Много моего кода было взято отсюда: http://stackoverflow.com/questions/15544116/sslhandshakeexception -received-fatal-alert-handshake-failure-when-setting-ciph – Avi
Выглядит довольно чисто, за исключением «System.setProperty» («https.protocols», «TLSv1»); линия. Есть ли способ, не устанавливающий некоторые системные вещи? У меня такая же проблема, и я хочу изолировать проблему, связанную с сертификатом, с одним компонентом. – Ruslan
@ Руслан - Вау, ты отвел меня с этим ответом.К сожалению, это было слишком давно, и с тех пор я уже сменил два рабочих места, поэтому у меня нет исходного кода, и я не мог вспомнить, почему я делал так, как сделал. Я почти уверен, что есть способ обойти это, я постараюсь посмотреть, смогу ли я найти другой способ, и если так, я отправлю его здесь. – Avi