REST-запрос в python аутентификации на основе сертификатов, работающей в SOAPUI - PullRequest
2 голосов
/ 04 апреля 2020

Я делаю REST-запрос к серверу https api, он работает в soapui, используя приведенную ниже конфигурацию, soapui rest request is successful

Я добавил сертификат в Настройки SSL> Keystore soapui ssl preferences

self-подписанный keystore.jks имеет пару ключей, которая является доверенной на сервере и проверяется для каждого запроса. Если сертификаты действительны, сервер вернет json

, пробовал это в python, используя этот код, он не работает, я получаю сообщение об ошибке на запросы SSL

.exceptions.SSLError: HTTPSConnectionPool (host = 'xlocal', port = 8014): Максимальное количество попыток превышено с помощью url: // api / path / here (вызвано SSLError (SSLError ("плохое рукопожатие: ошибка ([('процедуры SSL') , 'tls_process_server_certificate', 'сбой проверки сертификата')],) ",),))

#!/usr/bin/env python3
import sys
import requests

API_ENDPOINT = "https://xlocal:8xxx/api/test/list"

#pem keys are exported from the jks using keytool explorer or 
#openssl pkcs12 -in soapui-keystore.p12  -nokeys -out soapuicert.pem
#openssl pkcs12 -in soapui-keystore.p12  -nodes -nocerts -out soapuikey.pem
NEW_CERT = r"C:\Users\myuser\self-signed-exported.cert.pem"
NEW_KEY = r"C:\Users\myuser\self-signed-exported.key.pem"

def main(argv):

    get = requests.get(API_ENDPOINT, cert=(NEW_CERT, NEW_KEY))
    get2 = requests.get(API_ENDPOINT, verify=NEW_CERT)

    print(get)
    print(get2)

if __name__ == "__main__":
    main(sys.argv[1:])

Он работает на Java с использованием этого кода, приведенного ниже.


public void getforObject() {
        restTemplate = new RestTemplate();
        try (FileInputStream fis = new FileInputStream(Project.keystorePath)) {
            KeyStore keyStore = SSL.getKeyStore(fis, Project.keystorePassword);
            SSLSocketFactory sslSocketFactory = SSL.getSSLSocketFactory(keyStore, Project.keystorePassword, trustAllCerts);
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslSocketFactory, (hostname, session) -> true);
            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
            HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
            restTemplate.setRequestFactory(httpRequestFactory);

            String forObject = restTemplate.getForObject(LIST_URL, String.class);

        } catch (Exception e) {
            //SystemLogger.error("Error configuring ssl", e);
            throw new RuntimeException("Error: unable to configure ssl.", e);
        }
}

public class DummyX509TrustManager implements X509TrustManager {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        @Override
        public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString)
                throws CertificateException {
        }
        @Override
        public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString)
                throws CertificateException {
        }
}

В чем проблема? Есть ли лучший способ сделать это в python?

1 Ответ

0 голосов
/ 14 апреля 2020

Я подозреваю, что проблема не в вашем python коде, а в цепочке сертификатов, которую вы предоставляете.

Недостаточно предоставить сертификат для вашего закрытого ключа - вы должны предоставить сертификат для ваш ключ, а также все остальные сертификаты в цепочке, оканчивающиеся доверенным центром сертификации.

Команды openssl, которые вас просят выполнить, сбросят цепочку сертификатов (которая обычно публикуется c). То, что вы можете найти сертификат своего ключа в файле pem, не означает, что цепочка сертификатов завершена или правильна.

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