Ошибка при вызове VISA API из .NET Core - PullRequest
0 голосов
/ 01 июля 2019

Я пытаюсь сделать GET-запрос к VISA api из .NET Core, и я получаю следующее сообщение об ошибке в WebException

Учетные данные, предоставленные в пакете, не были распознаны visa

API-интерфейсы VISA поддерживают двустороннее SSL-соединение, и для этого виза выдает набор закрытого ключа и сертификата вместе с парой идентификатора пользователя и пароля.

Я создал сертификат p12файл, используя следующую команду согласно документации VISA.

openssl pkcs12 -export -in cert.pem -inkey "privateKey.pem" 
    -certfile cert.pem -out myProject_keyAndCertBundle.p12

Затем я написал следующий код, чтобы сделать запрос к API VISA.Я выполняю этот код как часть консольного приложения .NET Core.

public string MakeHelloWorldCall()
{
    string requestURL = "https://sandbox.api.visa.com/vdp/helloworld";

    string userId = ConfigurationManager.AppSettings["userId"];
    string password = ConfigurationManager.AppSettings["password"];
    string certificatePath = ConfigurationManager.AppSettings["cert"];
    string certificatePassword = ConfigurationManager.AppSettings["certPassword"];
    string statusCode = "";

    HttpWebRequest request = WebRequest.Create(requestURL) as HttpWebRequest;
    request.Method = "GET";

    request.Headers["Authorization"] = GetBasicAuthHeader(userId, password);

    var certificate = new X509Certificate2(certificatePath, certificatePassword);
    request.ClientCertificates.Add(certificate);

    try
    {
        // Make the call
        // This is the line which throws the exception.
        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        {
            statusCode = response.StatusCode.ToString();
        }
    }
    catch (WebException e)
    {
        Console.WriteLine(e.Message);
        Exception ex = e.InnerException;

        while(ex != null)
        {
            Console.WriteLine(ex.Message);
            ex = ex.InnerException;
        }

        if (e.Response is HttpWebResponse)
        {
            HttpWebResponse response = (HttpWebResponse)e.Response;
            statusCode = response.StatusCode.ToString();
        }
    }

    return statusCode;
}

private string GetBasicAuthHeader(string userId, string password)
{
    string authString = userId + ":" + password;
    var authStringBytes = Encoding.UTF8.GetBytes(authString);
    string authHeaderString = Convert.ToBase64String(authStringBytes);
    return "Basic " + authHeaderString;
}

Я вижу следующий вывод в консоли.

The SSL connection could not be established, see inner exception. The credentials supplied to the package were not recognized
The SSL connection could not be established, see inner exception.
The credentials supplied to the package were not recognized

Таким образом, корневая ошибка The credentials supplied to the package were not recognized.

Я застрял здесь, так как не уверен, что является причиной этой ошибки.

Я попытался найти эту ошибку в Google и SO.Но большинство сообщений подозревают, что у них недостаточно прав для доступа к сертификату.Но я использую Visual Studio с учетной записью администратора, а также использую файл сертификата, а не сертификат, установленный на машине.

Полагаю, любой, кто имеет опыт работы с двусторонним SSL-соединением и / или API-интерфейсами VISA, сможетчтобы понять, что именно является причиной этой ошибки.

РЕДАКТИРОВАТЬ : я могу успешно вызывать API из пользовательского интерфейса SOAP, где я настроил тот же сертификат .p12 и заголовок авторизации.

Ответы [ 2 ]

0 голосов
/ 01 июля 2019

Наконец, я смог решить эту проблему.

После двух вещей, которые я сделал, чтобы прийти к решению.

  1. Используйте HttpClient вместо HttpWebRequest, чтобы сделать запрос API.Благодаря @ Fred.
  2. Вместо использования файла сертификата я установил сертификат на машину в хранилище сертификатов текущего пользователя.

Ниже приведен рабочий код.

public string MakeHelloWorldCallUsingHttpClient()
{
    string requestURL = "https://sandbox.api.visa.com/vdp/helloworld";

    string userId = ConfigurationManager.AppSettings["userId"];
    string password = ConfigurationManager.AppSettings["password"];
    string apiResponse = "";

    HttpClientHandler clientHandler = new HttpClientHandler();

    HttpClient httpClient = new HttpClient(clientHandler);
    httpClient.DefaultRequestHeaders.Authorization 
            = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", GetBasicAuthHeaderValue(userId, password));
    try
    {
        // Make the call
        var response = httpClient.GetAsync(requestURL).Result;

        if (response.StatusCode == HttpStatusCode.OK)
        {
            apiResponse = response.Content.ReadAsStringAsync().Result;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        Exception ex = e.InnerException;
        while (ex != null)
        {
            Console.WriteLine(ex.Message);
            ex = ex.InnerException;
        }
    }
    return apiResponse;
}

private string GetBasicAuthHeaderValue(string userId, string password)
{
    string authString = userId + ":" + password;
    var authStringBytes = Encoding.UTF8.GetBytes(authString);
    return Convert.ToBase64String(authStringBytes);
}

Ниже приведен вывод, который я сейчас получаю из API.

{"timestamp":"2019-07-01T14:02:22","message":"helloworld"}

Следующая строка кода позволяет найти сертификаты клиента из хранилища сертификатов текущего пользователя.

clientHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;

При настройке от ClientCertificateOptions до ClientCertificateOption.Manual потребуется вручную добавить сертификат к clientHandler.ClientCertificates следующим образом.

var certificate = new X509Certificate2(certificatePath, certificatePassword);
clientHandler.ClientCertificates.Add(certificate);

Это приведет к той же ошибке, с которой я сталкиваюсь в настоящее время.

Это заставляет меня думать, что лучше всего позволить Framework найти клиентский сертификат.

0 голосов
/ 01 июля 2019

Используете ли вы полный IIS?Убедитесь, что ваш пул приложений имеет доступ к этому файлу

Как дать разрешение

Но сложно отладить то, к чему у вас нет доступа.

Пожалуйста, проверьте этот ответ

...