让TestRestTemplate与https一起使用

时间:2018-03-23 22:09:54

标签: spring-boot junit

为设置安全cookie的REST端点编写JUnit Integrtaion测试,无法通过ResourceAccessException错误。

要求是执行https://localhost:8443请求。

尝试过使用customRestTemplate

获取后续例外。

org.springframework.web.client.ResourceAccessException:“https://localhost:8443/dcs”的GET请求上的I / O错误:连接到localhost:8443 [localhost / 127.0.0.1,localhost / 0:0: 0:0:0:0:0:1]失败:连接被拒绝:连接;嵌套异常是org.apache.http.conn.HttpHostConnectException

以下是代码。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DcsServiceTests {

        @Autowired
        RestTemplateBuilder restTemplateBuilder;

        @Autowired
        private TestRestTemplate testRestTemplate;

        @Test
        public void testGet_ImageResponse() throws Exception {

            //Arrange

            //Act
            ResponseEntity<byte[]> response = testRestTemplate.getForEntity(url, byte[].class);

            //Assert
            //Response Status
            assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
            //Response has cookie
            assertThat(response.getHeaders().containsKey("Set-Cookie")).isTrue();
        }

        @PostConstruct
        public void initialize() {

            // Lambda expression not working, TBD - Java version used. 
            //TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;

            final TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
                @Override
                public boolean isTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    return true;
                }
            };

            HttpComponentsClientHttpRequestFactory requestFactory =
                    new HttpComponentsClientHttpRequestFactory();

            try {
                SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                        .loadTrustMaterial(null, acceptingTrustStrategy)
                        .build();

                SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);

                CloseableHttpClient httpClient = HttpClients.custom()
                        .setSSLSocketFactory(csf)
                        .build();

                requestFactory.setHttpClient(httpClient);           
            }
            catch (Exception e) {
                System.out.println("Exception occured creating Request Factory");
            }

            RestTemplate customTemplate = restTemplateBuilder
                .requestFactory(requestFactory)
                .rootUri("https://localhost:8443")
                .build();
            this.testRestTemplate = new TestRestTemplate(
                    customTemplate,
                    null, 
                    null,  // Not using basic auth 
                    TestRestTemplate.HttpClientOption.ENABLE_COOKIES); // Cookie support 

        }

    }

1 个答案:

答案 0 :(得分:0)

禁用SSL然后使用testRestTemplate和交换方法一起工作。安全的cookie也可以工作,只需要解析标头以验证单元测试用例中的结果

@Bean
public Boolean disableSSLValidation() throws Exception {
    final SSLContext sslContext = SSLContext.getInstance("TLS");

    sslContext.init(null, new TrustManager[] { new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    } }, null);

    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

    return true;
}


public void hostNameVerifier() {
    final HostnameVerifier defaultHostnameVerifier = javax.net.ssl.HttpsURLConnection.getDefaultHostnameVerifier ();
    final HostnameVerifier localhostAcceptedHostnameVerifier = new javax.net.ssl.HostnameVerifier () {
       public boolean verify ( String hostname, javax.net.ssl.SSLSession sslSession ) {
            if ( hostname.equals ( "localhost" ) ) {
                return true;
            }
             return defaultHostnameVerifier.verify ( hostname, sslSession );
        }
    };
    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier ( localhostAcceptedHostnameVerifier );
}

@Test
public void testGet_ImageResponse() throws Exception {

    //Arrange       
    String url = getUrl() +  "/xyz?s_action=test&s_type=i";

    //Act
    ResponseEntity<byte[]> response = restTemplate.getForEntity(url, byte[].class);

    //Assert
    //Response Status
    assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    //Response has cookie
    assertThat(response.getHeaders().containsKey("Set-Cookie")).isTrue();

    //Extract cookie from header
    List<String> cookies = response.getHeaders().get("Set-Cookie");

    //Construct cookie from RAW Header Response
    Cookie cookie = RawCookieParser.constructCookieFromHeaderResponse(response.getHeaders().get("Set-Cookie").toString());

    //Cookies name matches 
    //Cookie value cannot be matched because value is being set from external JAR
    assertEquals(cookie.getName(), appConfig.getName());

    //Cookie domain matches 
    assertEquals(cookie.getDomain(), appConfig.getDomain());

}

    public class RawCookieParser {


        /*
         * Construct a cookie object by parsing the HTTP Header response
         */
        public static Cookie constructCookieFromHeaderResponse(String input) throws Exception {

            String rawCookie = input.replace("[", "").replace("]", "");
            String[] rawCookieParams = rawCookie.split(";");
            String[] rawCookieNameAndValue = rawCookieParams[0].split("=");
            if (rawCookieNameAndValue.length != 2) {
                throw new Exception("Invalid cookie: missing name and value.");
            }
            String cookieName = rawCookieNameAndValue[0].trim();
            String cookieValue = rawCookieNameAndValue[1].trim();
            Cookie cookie = new Cookie(cookieName, cookieValue);

            for (int i = 1; i < rawCookieParams.length; i++) {
                String rawCookieParamNameAndValue[] = rawCookieParams[i].trim().split("=");
                String paramName = rawCookieParamNameAndValue[0].trim();

                if (rawCookieParamNameAndValue.length == 2) {

                    String paramValue = rawCookieParamNameAndValue[1].trim();
                    if (paramName.equalsIgnoreCase("secure"))  {
                        cookie.setSecure(true);                 
                    } else if (paramName.equalsIgnoreCase("max-age")) {
                        int maxAge = Integer.parseInt(paramValue);
                        cookie.setMaxAge(maxAge);
                    } else if (paramName.equalsIgnoreCase("domain")) {
                        cookie.setDomain(paramValue);
                    } else if (paramName.equalsIgnoreCase("path")) {
                        cookie.setPath(paramValue);
                    } 
                }
            }

           return cookie;
        }

    }