javascript
ssl/tls服务器瞬时_SSL / TLS REST服务器–带有Spring和TomEE的客户端
ssl/tls服務(wù)器瞬時(shí)
在構(gòu)建系統(tǒng)時(shí),開發(fā)人員通常會(huì)忽略安全性方面。 安全一直是令人擔(dān)憂的重要問題,但是它比以前吸引了更高的關(guān)注。 就在今年,我們發(fā)生了像Heartbleed Bug或CelebrityGate丑聞這樣的案件。 這與帖子無關(guān),只是安全真正重要的示例,我們應(yīng)該意識(shí)到這一點(diǎn)。
隨著REST服務(wù)的日益普及,有必要以某種方式確保這些安全。 幾周前,我不得不將客戶端與https后面的REST服務(wù)集成。 我以前從未做過,這就是這篇文章的原因。 我必須承認(rèn)我自己不是安全專家,所以如果我寫任何愚蠢的文章,請糾正我。
設(shè)置
對于此示例,我使用了以下設(shè)置:
- 具有SSL配置的 TomEE (或Tomcat )
- 彈簧
- Apache HTTP組件
我不會(huì)討論有關(guān)SSL和TSL的許多細(xì)節(jié),因此請?jiān)诖颂幉榭雌渌麅?nèi)容。 請注意,TLS是SSL演進(jìn)的新名稱。 有時(shí)兩者之間會(huì)有混淆,人們通常會(huì)說SSL,但使用的是TSL的最新版本。 記在腦子里。
不要忘記按照下一頁上的說明為Tomcat設(shè)置SSL: SSL Configuration HOW-TO 。 服務(wù)器需要向客戶端提供一組憑據(jù)(證書),以保護(hù)服務(wù)器和客戶端之間的連接。
代碼
服務(wù)
讓我們創(chuàng)建一個(gè)簡單的Spring REST服務(wù):
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> 。 需要這些來指定應(yīng)用程序需要安全連接。 選中“ 保護(hù) Java應(yīng)用程序的Web應(yīng)用程序安全” 。
運(yùn)行服務(wù)
只需使用您喜歡的IDE環(huán)境在TomEE服務(wù)器上部署應(yīng)用程序,然后訪問https://localhost:8443/ 。 您應(yīng)該獲得以下信息(您可能需要先接受服務(wù)器證書):
請注意,瀏覽器協(xié)議為https ,端口為8443 (假設(shè)您將默認(rèn)設(shè)置保留在SSL Configuration HOW-TO中) 。
客戶
現(xiàn)在,如果您嘗試使用Java客戶端調(diào)用此REST服務(wù),則很可能將獲得以下消息和Exception(或類似信息):
消息: GET請求“ https:// localhost:8443 /”上的I / O錯(cuò)誤:sun.security.validator.ValidatorException:
異常: 由 以下原因 引起:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路徑構(gòu)建失敗:sun.security.provider.certpath.SunCertPathBuilderException:無法找到到請求目標(biāo)的有效證書路徑
發(fā)生這種情況是因?yàn)檎谶\(yùn)行的JDK沒有針對您的服務(wù)器的有效證書。 您可以導(dǎo)入它,并解決該問題,但是讓我們做一些更有趣的事情。 我們將以編程方式向受信任的密鑰庫提供服務(wù)器證書。
這在以下情況下特別有用:
- 您正在將代碼運(yùn)行到多個(gè)環(huán)境中
- 您不必每次都手動(dòng)將證書導(dǎo)入JDK
- 如果您升級JDK,則必須記住有關(guān)證書的信息
- 由于某些奇怪的原因,您無權(quán)訪問JDK本身來導(dǎo)入證書
讓我們寫一些代碼:
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 ,它使我們能夠根據(jù)可信證書列表來驗(yàn)證服務(wù)器的身份。 證書是從KeyStore從服務(wù)器使用的同一文件中加載的 。
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());} }一個(gè)簡單的測試類。 我們還需要一個(gè)具有密鑰庫文件位置和密碼的屬性文件:
config.properties
keystore.file=${user.home}/.keystore keystore.pass=changeit如果您使用了所有默認(rèn)值,這應(yīng)該可以正常工作。
運(yùn)行測試
如果現(xiàn)在運(yùn)行在Java客戶端中調(diào)用REST服務(wù)的測試,則應(yīng)獲得以下輸出:
響應(yīng) : <200 OK,調(diào)用了get Rest服務(wù),{服務(wù)器= [Apache-Coyote / 1.1],緩存控制= [私有],到期時(shí)間= [星期四,1970年1月1日,周四,01:00:00 WET],內(nèi)容類型= ,Content-Length = [27],Date = [Tue,2014年12月23日01:29:20 GMT]}>
身體 : 叫得到休息服務(wù)
結(jié)論
而已! 現(xiàn)在,您可以以安全的方式與客戶端調(diào)用REST服務(wù)。 如果您希望將證書添加到JDK密鑰庫,請檢查此文章 。
敬請期待與Java EE JAX-RS等效的等效產(chǎn)品。
資源資源
您可以從我的github倉庫REST SSL克隆完整的工作副本。
翻譯自: https://www.javacodegeeks.com/2014/12/ssl-tls-rest-server-client-with-spring-and-tomee.html
ssl/tls服務(wù)器瞬時(shí)
總結(jié)
以上是生活随笔為你收集整理的ssl/tls服务器瞬时_SSL / TLS REST服务器–带有Spring和TomEE的客户端的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 相声演员师胜杰什么原因走的(师胜杰得的什
- 下一篇: java 性能调优_Java性能调优调查
