Почему я не могу принять все хосты для моего метода POST? - PullRequest
2 голосов
/ 23 октября 2019
  • Наш целевой сервер (censored.local) имеет сертификат HTTPS с CN = censored.com, * .censored.com
  • . При выполнении теста возникает исключение:
javax.net.ssl.SSLException: Certificate for 
"censored.local" doesn't match any of the subject alternative 
names: [censored.com, *.censored.com]
  • Я понимаю, почему это происходит (RFC 2818), но я бы хотел обойти это в целях тестирования. Невозможно установить другой сертификат на целевом сервере.
  • .relaxedHTTPSValidation () и .allowAllHostnames () не работали. Итак, я попытался закодировать свой путь в это:

Мой тестовый класс:

...
.given().spec(reqSpec)
...

Мой класс конфигурации:

public abstract class Configurator {
    protected static TestEnv envConf = chooseEnv();
    protected static RequestSpecification reqSpec;
    static { try { reqSpec = configureRestAssured(); } catch (Exception e) {e.printStackTrace(); } }

    protected static TestEnv chooseEnv() {
        // Some logic following to select an instance from TestEnv (not shown here)
        ...    
        envConf = TestEnv.BETA;
        return envConf;
    }
    protected static RequestSpecification configureRestAssured() {
        RequestSpecification reqSpec = new RequestSpecBuilder().build();
        reqSpec
                .header("Authorization", String.format("Bearer %s", envConf.getBearerToken()))
                // This gets the censored.local URI:
                .baseUri(envConf.getBaseURI())

                .config(getRAconfig());
        return reqSpec;
    }
    private static RestAssuredConfig getRAconfig() {
        SSLSocketFactory sslSocket = getSSLsocket (envConf.getKeystoreFile(), "keystorePassword", "PrivateKeyPassword");
        RestAssuredConfig raConfig = RestAssuredConfig.config()
        .sslConfig(SSLConfig.sslConfig().sslSocketFactory(sslSocket));
        return raConfig;
    }
    private static SSLSocketFactory getSSLsocket(String ksPath, String ksPassword, String pkPassword) {
        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(new FileInputStream(ksPath), ksPassword.toCharArray());
        SSLContext context = SSLContexts.custom()
                .loadKeyMaterial(keystore, pkPassword.toCharArray(), firstPrivateKeyStrategy())
                .loadTrustMaterial(trustEveryoneStrategy())
                .build();
        return new SSLSocketFactory(context);
    }
    private static PrivateKeyStrategy firstPrivateKeyStrategy() {
        return new PrivateKeyStrategy() {
            @Override
            public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
                return aliases.keySet().iterator().next();
            }
        };
    }
    private static TrustStrategy trustEveryoneStrategy() {
        return new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
                return true;
            }
        };
    }}
  • Iне знаю, помогает ли это, но во время отладки я вижу:
raConfig = {RestAssuredConfig@2752} 
 configs = {HashMap@2753}  size = 17
  ... 
  {Class@2003} "class io.restassured.config.SSLConfig" -> {SSLConfig@3257} 
   key = {Class@2003} "class io.restassured.config.SSLConfig"
   value = {SSLConfig@3257} 
    pathToKeyStore = null
    pathToTrustStore = null
    keyStorePassword = null
    trustStorePassword = null
    keyStoreType = "pkcs12"
    trustStoreType = "pkcs12"
    port = -1
    trustStore = null
    keyStore = null
    x509HostnameVerifier = {StrictHostnameVerifier@3286} "STRICT"

Показывает ли STRICT мою проблему? Если да, как взломать не-STRICT x509HostnameVerifier?

1 Ответ

1 голос
/ 07 ноября 2019

Я нашел способ настроить конфигурацию SSL так, как мне нужно. Слегка подвергнутый цензуре код прилагается. Ищите комментарий «Святой Грааль»:

 protected static RequestSpecification configureRestAssured() {
    // Create the ReqSpec instance:
    RequestSpecification reqSpecToBuild = new RequestSpecBuilder().build();
    // Configure more simple stuff for common request specification:
    reqSpecToBuild
            .header("Content-Type", "application/json")
            .baseUri(envConf.getBaseURI())
            .config(getRAconfig());
    return reqSpecToBuild; 
    }
// Add extended config object to the request spec:
private static RestAssuredConfig getRAconfig() {
    // Create a special socket with our keystore and ALLOW_ALL_HOSTNAME_VERIFIER:
    SSLSocketFactory sslSocket = getSSLsocket (envConf.getKeystoreFile(), somePass, somePass);
    // Create a configuration instance to load into the request spec via config():
    RestAssuredConfig raConfigToBuild = RestAssuredConfig.config()
            // Set SSL configuration into the RA configuration, with an SSLConfig object, that refers to our socket:
            .sslConfig(SSLConfig.sslConfig().sslSocketFactory(sslSocket));
    return raConfigToBuild;
}
private static SSLSocketFactory getSSLsocket(String ksPath, String ksPassword, String pkPassword) {
    KeyStore keystore = KeyStore.getInstance("PKCS12");
    // Load keystore file and password:
    keystore.load(new FileInputStream(ksPath), ksPassword.toCharArray());
    SSLContext context = SSLContexts.custom()
            .loadKeyMaterial(keystore, pkPassword.toCharArray())
            .build();
    // This is the holy grail:
    SSLSocketFactory sslSocketToBuild = new SSLSocketFactory(context, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    return sslSocketToBuild;
}
}

Обратите внимание, что я не просто предоставляю один аргумент конструктору SSLSocketFactory, но я предоставляю обычный аргумент (контекст), а также аргумент ALLOW_ALL_HOSTNAME_VERIFIER - этоимеет значение!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...