복붙노트

[SPRING] 스프링 부트 SSL 클라이언트

SPRING

스프링 부트 SSL 클라이언트

나는 Spring Boot가 처음이다. 지금까지 나는 그것을 즐기고있다. 상호 X.509 인증서 인증을 올바르게 처리하는 데모 SSL Rest 웹 서버를 개발했습니다. 자체 서명 된 클라이언트 및 서버 인증서가있는 IE 브라우저를 사용하여 데모 레스트 웹 서버가 올바르게 작동하는지 테스트했습니다. 서버와 브라우저가 서로 인증서를 성공적으로 교환하고 유효성을 검사합니다.

클라이언트 인증서를 포함하고 https를 발급하는 방법을 보여주는 SSL 클라이언트 예제를 찾는 데 문제가 있습니다. 누구나 내 SSLS 서버를 소비하는 방법을 보여주는 간단한 휴식 클라이언트 예제가 있습니까?

친애하는, 스티브 맨스필드

해결법

  1. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    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);
    
  6. from https://stackoverflow.com/questions/30770280/spring-boot-ssl-client by cc-by-sa and MIT license