使用 Spring RestTemplate 訪問 HTTPS REST 服務
一、概述
在本教程中,我們將了解如何使用 Spring 的RestTemplate
使用通過 HTTPS 保護的 REST 服務。
2.設置
我們知道,要保護 REST 服務,我們需要證書和從證書生成的密鑰庫。我們可以從證書頒發機構 (CA) 獲得證書,以確保應用程序是安全的,並且對於生產級應用程序是可信的。
出於本文的目的,我們將在示例應用程序中使用自簽名證書。
我們將使用 Spring 的RestTemplate
來使用 HTTPS REST 服務。
首先,讓我們創建一個控制器類WelcomeController
和一個返回簡單String
響應的/welcome
端點:
@RestController
public class WelcomeController {
@GetMapping(value = "/welcome")
public String welcome() {
return "Welcome To Secured REST Service";
}
}
然後,讓我們在src/main/resources
文件夾中添加我們的密鑰庫:
接下來,讓我們將與密鑰庫相關的屬性添加到我們的application.properties
文件中:
server.port=8443
server.servlet.context-path=/
# The format used for the keystore
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:keystore/baeldung.p12
# The password used to generate the certificate
server.ssl.key-store-password=password
# The alias mapped to the certificate
server.ssl.key-alias=baeldung
我們現在可以在此端點訪問 REST 服務: https://localhost:8443/welcome
3. 使用安全的 REST 服務
Spring 提供了一個方便的RestTemplate
類來使用 REST 服務。
雖然使用簡單的 REST 服務很簡單,但在使用安全服務時,我們需要使用服務使用的證書/密鑰庫自定義RestTemplate
。
接下來,讓我們創建一個簡單的RestTemplate
對象並通過添加所需的證書/密鑰庫對其進行自定義。
3.1.創建RestTemplate
客戶端
讓我們編寫一個簡單的控制器,它使用RestTemplate
來使用我們的 REST 服務:
@RestController
public class RestTemplateClientController {
private static final String WELCOME_URL = "https://localhost:8443/welcome";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/welcomeclient")
public String greetMessage() {
String response = restTemplate.getForObject(WELCOME_URL, String.class);
return response;
}
}
如果我們運行我們的代碼並訪問/welcomeclient
端點,我們將收到錯誤消息,因為無法找到訪問安全 REST 服務的有效證書:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
接下來,我們將了解如何解決此錯誤。
3.2.為 HTTPS 訪問配置RestTemplate
訪問安全 REST 服務的客戶端應用程序應在其resources
文件夾中包含一個安全密鑰庫。此外,還需要配置RestTemplate
本身。
首先,讓我們將之前的密鑰庫baeldung.p12
添加為/src/main/resources
文件夾中的信任庫:
接下來,我們需要在application.properties
文件中添加信任庫詳細信息:
server.port=8082
#trust store location
trust.store=classpath:keystore/baeldung.p12
#trust store password
trust.store.password=password
最後,讓我們通過添加信任庫來自定義RestTemplate
:
@Configuration
public class CustomRestTemplateConfiguration {
@Value("${trust.store}")
private Resource trustStore;
@Value("${trust.store.password}")
private String trustStorePassword;
@Bean
public RestTemplate restTemplate() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException,
CertificateException, MalformedURLException, IOException {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build();
SSLConnectionSocketFactory sslConFactory = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConFactory).build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}
}
讓我們詳細了解上面restTemplate()
方法中的重要步驟。
首先,我們創建一個表示安全套接字協議實現的SSLContext
對象。我們使用SSLContextBuilder
類的build()
方法來創建它。
我們使用SSLContextBuilder
的loadTrustMaterial
() 方法將密鑰庫文件和憑證加載到SSLContext
對像中。
然後,我們通過加載SSLContext.
創建SSLConnectionSocketFactory,
這是一個用於 TSL 和 SSL 連接的分層套接字工廠。這一步的目的是驗證服務器是否正在使用我們在上一步加載的可信證書列表,即對服務器進行身份驗證。
現在我們可以使用自定義的RestTemplate
在端點使用安全的 REST 服務: http://localhost:8082/welcomeclient:
4.結論
在本文中,我們討論瞭如何使用自定義的RestTemplate
使用安全的 REST 服務。
一如既往,源代碼可 在 GitHub 上獲得。