[SPRING] 스프링 부트 SSL 클라이언트
SPRING스프링 부트 SSL 클라이언트
나는 Spring Boot가 처음이다. 지금까지 나는 그것을 즐기고있다. 상호 X.509 인증서 인증을 올바르게 처리하는 데모 SSL Rest 웹 서버를 개발했습니다. 자체 서명 된 클라이언트 및 서버 인증서가있는 IE 브라우저를 사용하여 데모 레스트 웹 서버가 올바르게 작동하는지 테스트했습니다. 서버와 브라우저가 서로 인증서를 성공적으로 교환하고 유효성을 검사합니다.
클라이언트 인증서를 포함하고 https를 발급하는 방법을 보여주는 SSL 클라이언트 예제를 찾는 데 문제가 있습니다. 누구나 내 SSLS 서버를 소비하는 방법을 보여주는 간단한 휴식 클라이언트 예제가 있습니까?
친애하는, 스티브 맨스필드
해결법
-
==============================
1.Spring을 사용한다면 Spring의 RestTemplate과 Apache의 HttpClient를 클라이언트 인증서로 구성하고 서버에서 자체 서명 된 인증서를 신뢰하는 방법을 보여주는 예제가 있습니다.
Spring을 사용한다면 Spring의 RestTemplate과 Apache의 HttpClient를 클라이언트 인증서로 구성하고 서버에서 자체 서명 된 인증서를 신뢰하는 방법을 보여주는 예제가 있습니다.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(new FileInputStream(new File("keystore.jks")), "secret".toCharArray()); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( new SSLContextBuilder() .loadTrustMaterial(null, new TrustSelfSignedStrategy()) .loadKeyMaterial(keyStore, "password".toCharArray()).build()); HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( httpClient); RestTemplate restTemplate = new RestTemplate(requestFactory); ResponseEntity<String> response = restTemplate.getForEntity( "https://localhost:8443", String.class);
-
==============================
2.Andy가 제출 한 위의 고객에게 일하도록 요청할 수 없습니다. 나는 "localhost! = clientname"이라고 말하는 오류가 계속 발생했다. 어쨌든, 나는 제대로 작동하도록했습니다.
Andy가 제출 한 위의 고객에게 일하도록 요청할 수 없습니다. 나는 "localhost! = clientname"이라고 말하는 오류가 계속 발생했다. 어쨌든, 나는 제대로 작동하도록했습니다.
import java.io.IOException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.methods.GetMethod; public class SSLClient { static { System.setProperty("javax.net.ssl.trustStore","c:/apachekeys/client1.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "password"); System.setProperty("javax.net.ssl.keyStore", "c:/apachekeys/client1.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "password"); } public static void main(String[] args) throws HttpException, IOException { HttpClient client = new HttpClient(); GetMethod method = new GetMethod(); method.setURI(new URI("https://localhost:8443/restserver", false)); client.executeMethod(method); System.out.println(method.getResponseBodyAsString()); } }
-
==============================
3.user1707141의 예제는 나를 위해 작동하지 않았고 skmansfield는 Spring Boot / Maven을 사용하지 않는 특정 파일에 의존합니다. 또한 앤디 윌킨슨 (Andy Wilkinson)의 답변은 SSLConnectionSocketFactory 생성자를 사용합니다. SSLConnectionSocketFactory는 Apache httpclient 4.4 이상에서 더 이상 사용되지 않으며 매우 복잡해 보입니다.
user1707141의 예제는 나를 위해 작동하지 않았고 skmansfield는 Spring Boot / Maven을 사용하지 않는 특정 파일에 의존합니다. 또한 앤디 윌킨슨 (Andy Wilkinson)의 답변은 SSLConnectionSocketFactory 생성자를 사용합니다. SSLConnectionSocketFactory는 Apache httpclient 4.4 이상에서 더 이상 사용되지 않으며 매우 복잡해 보입니다.
그래서 여기에 100 % 이해할 수있는 예제 프로젝트를 만들었습니다 : https://github.com/jonashackt/spring-boot-rest-clientcertificate
TestTemplate에서 @Autowired를 사용하여 RestTemplate을 정상적으로 사용하는 것 외에도 RestTemplate을 다음과 같이 구성해야합니다.
package de.jonashackt.restexamples; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.util.ResourceUtils; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; @Configuration public class RestClientCertTestConfiguration { private String allPassword = "allpassword"; @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception { SSLContext sslContext = SSLContextBuilder .create() .loadKeyMaterial(ResourceUtils.getFile("classpath:keystore.jks"), allPassword.toCharArray(), allPassword.toCharArray()) .loadTrustMaterial(ResourceUtils.getFile("classpath:truststore.jks"), allPassword.toCharArray()) .build(); HttpClient client = HttpClients.custom() .setSSLContext(sslContext) .build(); return builder .requestFactory(new HttpComponentsClientHttpRequestFactory(client)) .build(); } }
-
==============================
4.나는 그것의 너무 늦은 것을 알고있다. 그러나 여기에 나를 위해 일하는 코드가있다.
나는 그것의 너무 늦은 것을 알고있다. 그러나 여기에 나를 위해 일하는 코드가있다.
@SpringBootApplication public class Application { 개인 정적 최종 로거 log = LoggerFactory.getLogger (Application.class); public static void main (String args []) { makeWebServiceCall (); } public static void makeWebServiceCall () { TrustStrategy acceptingTrustStrategy = (X509Certificate [] chain, String authType) -> 참; SSLContext sslContext; ResponseEntity
response = null; 시도 { sslContext = org.apache.http.ssl.SSLContexts.custom (). loadTrustMaterial (null, acceptingTrustStrategy) .짓다(); SSLConnectionSocketFactory csf = 새로운 SSLConnectionSocketFactory (sslContext); CloseableHttpClient httpClient = HttpClients.custom (). setSSLSocketFactory (csf) .build (); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory (); requestFactory.setHttpClient (httpClient); RestTemplate restTemplate = 새로운 RestTemplate (requestFactory); StringBuffer plainCreds = 새로운 StringBuffer (); plainCreds.append ( "username"); plainCreds.append ( ":"); plainCreds.append ( "password"); byte [] plainCredsBytes = plainCreds.toString (). getBytes (); byte [] base64CredsBytes = Base64.getEncoder (). encode (plainCredsBytes); 문자열 userBase64Credentials = 새 문자열 (base64CredsBytes); HttpHeaders 헤더 = 새로운 HttpHeaders (); headers.add ( "Authorization", "Basic"+ userBase64Credentials); headers.setAccept (Collections.singletonList (MediaType.APPLICATION_JSON)); headers.setContentType (MediaType.APPLICATION_JSON); HttpEntity 엔티티 = 새로운 HttpEntity <> (헤더); String url = "https : restUrl"; 응답 = restTemplate.exchange (url, HttpMethod.GET, entity, String.class); if (response.getStatusCodeValue () == 200) { log.info ( "성공! 필요에 따라 추가 처리"); } else { log.info ( "***************받은 상태 코드 :"+ response.getStatusCodeValue () + ". **************** ********* "); } } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { log.error ( "예외가 발생했습니다. 다음은 예외 세부 사항입니다.", e); } catch (HttpClientErrorException e) { if (e.getRawStatusCode () == 403) { log.info ( "*************** 상태 코드 수신 :"+ e.getRawStatusCode () + "요청한 리소스에 대한 액세스 권한이 없습니다. ***** ******************* "); } else if (e.getRawStatusCode () == 404) { log.info ( "*************** 상태 코드가 수신 됨 :"+ e.getRawStatusCode () + "리소스가 존재하지 않음 (또는) 서비스가 작동하지 않음 ** ********************** "); } else if (e.getRawStatusCode () == 400) { log.info ( "*************** 상태 코드 수신 :"+ e.getRawStatusCode () + ". 잘못된 요청. ************ ************ "); } else { log.info ( "***************받은 상태 코드 :"+ e.getRawStatusCode () + ". **************** ********* "); } log.info ( "*************** 응답 본문 :"+ e.getResponseBodyAsString () + "***************** ******* "); } } } 여기에 제기 된 Maven이 있습니다.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>gs-consuming-rest</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.6</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
==============================
5.이것은 나를 위해 일했다 :
이것은 나를 위해 일했다 :
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true; javax.net.ssl.SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom() .loadTrustMaterial(null, acceptingTrustStrategy).build(); SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(requestFactory);
from https://stackoverflow.com/questions/30770280/spring-boot-ssl-client by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 테스트 클래스가 더러워진 후에 Spring JUnit 애플리케이션 컨텍스트를 어떻게 재설정합니까? (0) | 2019.01.01 |
---|---|
[SPRING] Spring 3.0 : XML 스키마 네임 스페이스 용 Spring NamespaceHandler를 찾을 수 없다. (0) | 2019.01.01 |
[SPRING] 다른 환경에서 스프링 빈을 정의 할 때 일반적인 전략 (0) | 2019.01.01 |
[SPRING] junit 테스트를 개선하려면 어떻게해야합니까? (0) | 2019.01.01 |
[SPRING] 바인딩 전 JSR-303 유형 검사 (0) | 2019.01.01 |