【问题标题】:Getting TestRestTemplate to work with https让 TestRestTemplate 与 https 一起工作
【发布时间】:2018-09-02 16:16:16
【问题描述】:

为设置安全 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 

        }

    }

【问题讨论】:

    标签: spring-boot junit


    【解决方案1】:

    禁用 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;
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 2016-12-13
      • 2016-10-06
      • 2011-11-30
      • 2014-02-19
      相关资源
      最近更新 更多