Я настраиваю сервер, который должен взаимодействовать с другими доверенными серверами, и я использую SSL Handshake при весенней загрузке с apache tomcat.
Мне удалось создать двухсторонний SSL, однако, если я добавлю Root CA, который сгенерировал сертификаты в хранилище доверенных сертификатов, он автоматически доверяет каждому дочернему элементу этого CA. Я хочу, чтобы он проверил, находится ли этот конкретный сертификат в доверенном хранилище не только от того же родителя.
Свойства приложения одинаковы для второго сервера, только с разными KeyStore и Truststore.
Application.properties
server.ssl.key-store=classpath:booker.p12
server.ssl.key-store-password=pass
server.ssl.key-password=pass
server.ssl.key-alies=booker
server.ssl.trust-store=classpath:bookerTrust.p12
server.ssl.trust-store-password=pass
server.ssl.trust-store-type = PKCS12
server.ssl.client-auth=need
server.port=8111
Настройка RestTemplate в main.java
@Bean
public RestTemplate restTemplate() throws Exception {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
restTemplate.setErrorHandler(
new DefaultResponseErrorHandler() {
@Override
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
return restTemplate;
}
private ClientHttpRequestFactory clientHttpRequestFactory() throws Exception {
return new HttpComponentsClientHttpRequestFactory(httpClient());
}
private HttpClient httpClient() throws Exception {
// Load our keystore and truststore containing certificates that we trust.
SSLContext sslcontext =
SSLContexts.custom().loadTrustMaterial(trustResource.getFile(), trustStorePassword.toCharArray())
.loadKeyMaterial(keyStore.getFile(), keyStorePassword.toCharArray(),
keyPassword.toCharArray()).build();
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslcontext, new HostCustomVerifer(trustResource,trustStorePassword,trustStoreType));
return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
}
}
Связь в контроллере:
@RestController
@RequestMapping(value = "/server1")
public class ClientController {
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/data", method = RequestMethod.GET)
ResponseEntity<?> getMessage(ServletRequest request) {
return ResponseEntity.ok("Server1 successfully called!");
}
@RequestMapping(value = "/sdata", method = RequestMethod.GET)
public ResponseEntity<String> getMsData() {
try {
String msEndpoint = https://localhost:8111/api/server2/data";
return new ResponseEntity<String>( restTemplate.getForObject(new URI(msEndpoint), String.class), HttpStatus.OK) ;
} catch (Exception ex) {
ex.printStackTrace();
}
return new ResponseEntity<String>("Exception occurred.. so, returning default data", HttpStatus.BAD_GATEWAY);
}
}
Я ожидаю, что этот сценарий потерпит неудачу, однако он будет успешным:
Сервер1: Доверительный RootCA, Сервер1, Сервер2
Сервер2: Доверительный RootCA, Сервер2
Сервер1 начинает связь с Сервером2 и каким-то образом преуспевает
Я ожидаю, что произойдет сбой, потому что Server2 не доверяет Server1