javascript
SSL / TLS REST服务器–带有Spring和TomEE的客户端
在構建系統時,開發人員通常會忽略安全性方面。 安全一直是令人擔憂的重要問題,但是它比以前吸引了更高的關注。 就在今年,我們發生了像Heartbleed Bug或CelebrityGate丑聞這樣的案件。 這與帖子無關,只是安全真正重要的示例,我們應該意識到這一點。
隨著REST服務的日益普及,有必要以某種方式確保這些安全。 幾周前,我不得不將客戶端與https后面的REST服務集成。 我以前從未做過,這就是這篇文章的原因。 我必須承認自己不是安全專家,所以如果我寫任何愚蠢的文章,請糾正我。
設置
對于此示例,我使用了以下設置:
- 具有SSL配置的 TomEE (或Tomcat )
- 彈簧
- Apache HTTP組件
我不會討論有關SSL和TSL的許多詳細信息,因此請在此處查看其他內容。 請注意,TLS是SSL演進的新名稱。 有時兩者之間會產生混淆,人們通常會說SSL,但使用的是TSL的最新版本。 記住這一點。
不要忘記按照下一頁上的說明為Tomcat設置SSL: SSL Configuration HOW-TO 。 服務器需要向客戶端提供一組憑據(證書),以保護服務器與客戶端之間的連接。
編碼
服務
讓我們創建一個簡單的Spring REST服務:
RestService.java
@Controller @RequestMapping("/") public class RestService {@RequestMapping(method = RequestMethod.GET)@ResponseBodypublic String get() {return "Called the get Rest Service";} }而且,我們還需要一些接線來使其工作:
RestConfig.java
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.radcortez.rest.ssl") public class RestConfig {}web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-appversion="3.1"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"><servlet><servlet-name>rest</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></init-param><init-param><param-name>contextConfigLocation</param-name><param-value>com.radcortez.rest.ssl</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>rest</servlet-name><url-pattern>/</url-pattern></servlet-mapping><security-constraint><web-resource-collection><web-resource-name>Rest Application</web-resource-name><url-pattern>/*</url-pattern></web-resource-collection><user-data-constraint><!-- Needed for our application to respond to https requests --><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint></security-constraint> </web-app>請注意元素security-constraint , user-data-constraint和<transport-guarantee>CONFIDENTIAL</transport-guarantee> 。 需要這些來指定應用程序需要安全連接。 選中“ 保護 Java應用程序的Web應用程序安全” 。
運行服務
只需使用您喜歡的IDE環境在TomEE服務器上部署應用程序,然后訪問https://localhost:8443/ 。 您應該獲得以下信息(您可能需要先接受服務器證書):
請注意,瀏覽器協議為https ,端口為8443 (假設您將默認設置保留在SSL Configuration HOW-TO中) 。
客戶
現在,如果您嘗試使用Java客戶端調用此REST服務,則很可能將獲得以下消息和Exception(或類似信息):
消息: GET請求“ https:// localhost:8443 /”上的I / O錯誤:sun.security.validator.ValidatorException:
異常: 由 以下原因 引起:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路徑構建失敗:sun.security.provider.certpath.SunCertPathBuilderException:無法找到到請求目標的有效證書路徑
發生這種情況是因為正在運行的JDK沒有針對您的服務器的有效證書。 您可以導入它,并解決該問題,但是讓我們做一些更有趣的事情。 我們將以編程方式為受信任的密鑰庫提供服務器證書。
這在以下情況下特別有用:
- 您正在將代碼運行到多個環境中
- 您不必每次都手動將證書導入JDK
- 如果您升級JDK,則必須記住有關證書的信息
- 由于某些奇怪的原因,您無權訪問JDK本身來導入證書
讓我們寫一些代碼:
RestClientConfig.java
@Configuration @PropertySource("classpath:config.properties") public class RestClientConfig {@Beanpublic RestOperations restOperations(ClientHttpRequestFactory clientHttpRequestFactory) throws Exception {return new RestTemplate(clientHttpRequestFactory);}@Beanpublic ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {return new HttpComponentsClientHttpRequestFactory(httpClient);}@Beanpublic HttpClient httpClient(@Value("${keystore.file}") String file,@Value("${keystore.pass}") String password) throws Exception {KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());FileInputStream instream = new FileInputStream(new File(file));try {trustStore.load(instream, password.toCharArray());} finally {instream.close();}SSLContext sslcontext =SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();SSLConnectionSocketFactory sslsf =new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1.2"}, null,BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);return HttpClients.custom().setSSLSocketFactory(sslsf).build();}@Beanpublic static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {return new PropertySourcesPlaceholderConfigurer();} }在這里,我們使用Spring RestOperations接口,該接口指定了一組基本的RESTful操作。 接下來,我們使用Apache HTTP組件SSLConnectionSocketFactory ,它使我們能夠根據可信證書列表來驗證服務器的身份。 證書從KeyStore從服務器使用的同一文件中加載 。
RestServiceClientIT.java
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RestClientConfig.class) public class RestServiceClientIT {@Autowiredprivate RestOperations rest;@Testpublic void testRestRequest() throws Exception {ResponseEntity response = rest.getForEntity("https://localhost:8443/", String.class);System.out.println("response = " + response);System.out.println("response.getBody() = " + response.getBody());} }一個簡單的測試類。 我們還需要一個具有密鑰庫文件位置和密碼的屬性文件:
config.properties
keystore.file=${user.home}/.keystore keystore.pass=changeit如果您使用了所有默認值,這應該可以正常工作。
運行測試
如果現在運行在Java客戶端中調用REST服務的測試,則應獲得以下輸出:
響應 : <200 OK,調用了get Rest服務,{服務器= [Apache-土狼/1.1],緩存控制= [私有],到期時間= [星期四,1970年1月1日,周四,01:00:00 WET],內容類型= ,Content-Length = [27],Date = [Tue,2014年12月23日,格林尼治標準時間]]>
身體 : 叫得到休息服務
結論
而已! 現在,您可以以安全的方式與客戶端調用REST服務。 如果您希望將證書添加到JDK密鑰庫,請檢查此文章 。
敬請期待與Java EE JAX-RS等效的等效產品。
資源資源
您可以從我的github倉庫REST SSL克隆完整的工作副本。
翻譯自: https://www.javacodegeeks.com/2014/12/ssl-tls-rest-server-client-with-spring-and-tomee.html
總結
以上是生活随笔為你收集整理的SSL / TLS REST服务器–带有Spring和TomEE的客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上汽8月整车销量42.3万辆 新能源销量
- 下一篇: 公交车里的急救室:国内首个大型 5G 移