Ecco un codice che ti darà l'idea generale.
È necessario creare un numero personalizzato ClientHttpRequestFactory
per fidarsi del certificato. Ecco come si presenta:
final ClientHttpRequestFactory clientHttpRequestFactory =
new MyCustomClientHttpRequestFactory(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER, serverInfo);
restTemplate.setRequestFactory(clientHttpRequestFactory);
Questa è l'implementazione per 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;
}
}
In questo caso il mio oggetto serverInfo
contiene l'identificazione del server. È necessario implementare l'interfaccia TrustManager
per ottenere il SslThumbprintVerifier
o qualsiasi altro metodo che si desidera verificare il certificato (è anche possibile decidere di restituire sempre anche true
).
Il valore org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
consente tutti i nomi host. Se è necessario verificare il nome host, , sarà necessario implementarlo in modo diverso.
Non sono sicuro di utente e password e di come è stato implementato. Spesso, è necessario aggiungere un'intestazione allo restTemplate
denominato Authorization
con un valore simile al seguente: Base: <encoded user+password>
. Il user+password
deve essere codificato Base64
.
Un sacco del mio codice è stato preso da qui: http://stackoverflow.com/questions/15544116/sslhandshakeexception -received-fatal-alert-handshake-failure-when-setting-ciph – Avi
Sembra abbastanza pulito ad eccezione di "System.setProperty (" https.protocols "," TLSv1 ");" linea. C'è un modo senza impostare alcune cose a livello di sistema? Sto riscontrando un problema simile e desidero isolare il problema relativo al certificato su un solo bean. – Ruslan
@Ruslan - Wow, mi hai riportato indietro con questa risposta.Sfortunatamente, è passato troppo tempo e ho già cambiato due postazioni di lavoro da allora, quindi non ho il codice sorgente e non riesco a ricordare perché ho fatto le cose come ho fatto io. Sono abbastanza sicuro che ci fosse un modo per aggirarlo, proverò a vedere se riesco a trovare un altro modo e in tal caso lo posterò qui. – Avi